社区导航

 

搜索
查看: 5353|回复: 24

[传感器MCU驱动例程] ST各类传感器MCU驱动程序总资源包

  [复制链接]

86

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-7-5 17:58 | 显示全部楼层 |阅读模式
资源包:
mcu driver 0705a.rar (393.19 KB, 下载次数: 583)


回复

使用道具 举报

15

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-7-5 20:55 | 显示全部楼层
,支持一下,收下备用。


回复

使用道具 举报

5701

TA的帖子

9

TA的资源

版主

Rank: 6Rank: 6

发表于 2017-7-6 17:27 | 显示全部楼层
看了一个,这个驱动太毕了

  1. /******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
  2. * File Name          : main_LIS3DSH_example_.c
  3. * Author             : MEMS Application Team
  4. * Version            : v1.1
  5. * Date               : 05 May 2016  
  6. * Description        : EKSTM32 main file
  7. *
  8. ********************************************************************************
  9. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  10. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
  11. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  12. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  13. * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  14. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  15. *
  16. * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
  17. *******************************************************************************/


  18. /* Includes ------------------------------------------------------------------*/
  19. //include files for MKI109V1 board
  20. #include "stm32f10x.h"
  21. #include "i2c_mems.h"
  22. #include "hw_config.h"


  23. //include MEMS driver
  24. #include "LIS3DSH_ACC_driver.h"

  25. /* Private typedef -----------------------------------------------------------*/
  26. /* Private define ------------------------------------------------------------*/
  27. /* Private macro -------------------------------------------------------------*/
  28. /* Private variables ---------------------------------------------------------*/
  29. /* Extern variables ----------------------------------------------------------*/
  30. /* Private function prototypes -----------------------------------------------*/
  31. /* Private functions ---------------------------------------------------------*/
  32. void Function_Error(void);


  33. /*******************************************************************************
  34. * Function Name  : main.
  35. * Description    : Main routine.
  36. * Input          : None.
  37. * Output         : None.
  38. * Return         : None.
  39. *******************************************************************************/
  40.   
  41. int main(void)
  42. {
  43.   u8_t dummy=0;
  44.   Type3Axis16bit_U data;

  45.   //Initialize your hardware here
  46.   
  47.   //function for MKI109V1 board
  48.   InitHardware();
  49.   I2C_MEMS_Init();   
  50.   
  51.   //Get device information to check
  52.   if(! LIS3DSH_ACC_GetWHO_AM_I(0, &dummy))
  53.     Function_Error();
  54.   if ( dummy != LIS3DSH_ACC_I_AM_LIS3DSH )
  55.     Function_Error();
  56.   
  57.   //Set device parameter
  58.   if(! LIS3DSH_ACC_SetFullScale(0, LIS3DSH_ACC_FULLSCALE_2))
  59.             Function_Error();
  60.   if(! LIS3DSH_ACC_SetAxis(0, LIS3DSH_ACC_X_ENABLE | LIS3DSH_ACC_Y_ENABLE | LIS3DSH_ACC_Z_ENABLE))
  61.             Function_Error();
  62.   if(!LIS3DSH_ACC_SetODR(0, LIS3DSH_ACC_ODR_3_125))
  63.      Function_Error();
  64.   
  65.   while(1){   
  66.     //Get Device Status       
  67.     if(! LIS3DSH_ACC_GetSatusReg(0, &dummy))
  68.        Function_Error();
  69.    
  70.      //Check if new data are available       
  71.      if ( dummy&LIS3DSH_ACC_STATUS_REG_ZYXDA ){
  72.         //Get new data
  73.         if(! LIS3DSH_ACC_GetAccAxesRaw(0, &data))
  74.           Function_Error();
  75.      }
  76.   }  
  77.   
  78. } // end main


  79. /*******************************************************************************
  80. * Function Name  : Function_Error
  81. * Description    : Generic Error function
  82. * Input          : None
  83. * Output         : None
  84. * Return         : None
  85. *******************************************************************************/
  86. void Function_Error(void)
  87. {
  88.     while(1);
  89. }



  90. //function for MKI109V1 board
  91. #ifdef USE_FULL_ASSERT
  92. /*******************************************************************************
  93. * Function Name  : assert_failed
  94. * Description    : Reports the name of the source file and the source line number
  95. *                  where the assert_param error has occurred.
  96. * Input          : - file: pointer to the source file name
  97. *                  - line: assert_param error line source number
  98. * Output         : None
  99. * Return         : None
  100. *******************************************************************************/
  101. void assert_failed(uint8_t* file, uint32_t line)
  102. {
  103.   /* User can add his own implementation to report the file name and line number,
  104.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  105.   /* Infinite loop */
  106.   while (1)
  107.   {}
  108. }
  109. #endif

  110. /******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
复制代码

  1. /******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
  2. * File Name          : LIS3DSH_ACC_driver.c
  3. * Author             : MEMS Application Team
  4. * Version            : v1.1
  5. * Date               : 05 Maggio 2016   
  6. * Description        : LIS3DSH Platform Independent Driver
  7. *
  8. ********************************************************************************
  9. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  10. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
  11. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  12. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  13. * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  14. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  15. *
  16. * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
  17. *******************************************************************************/

  18. /* Includes ------------------------------------------------------------------*/
  19. #include "LIS3DSH_ACC_driver.h"

  20. /* Private typedef -----------------------------------------------------------*/

  21. /* Private define ------------------------------------------------------------*/

  22. /* Private macro -------------------------------------------------------------*/

  23. /* Private variables ---------------------------------------------------------*/

  24. /* Private function prototypes -----------------------------------------------*/

  25. /************** Generic Function  *******************/

  26. /*******************************************************************************
  27. * Function Name : LIS3DSH_ACC_ReadReg
  28. * Description   : Generic Reading function. It must be fullfilled with either
  29. *               : I2C or SPI reading functions
  30. * Input         : Register Address
  31. * Output        : Data REad
  32. * Return                        : None
  33. *******************************************************************************/
  34. status_t LIS3DSH_ACC_ReadReg(void *handle, u8_t Reg, u8_t *Bufp, u16_t len)
  35. {
  36.    
  37.   //To be completed with either I2c or SPI writing function
  38.   //i.e.: SPI_Mems_Write_Reg(Reg, Data);
  39.   //I2Cx_Read(Bufp, LIS3DSH_ACC_I2C_ADDRESS_HIGH, Reg, len);    //[Example]
  40.   return MEMS_SUCCESS;
  41. }

  42. /*******************************************************************************
  43. * Function Name : LIS3DSH_ACC_WriteReg
  44. * Description   : Generic Writing function. It must be fullfilled with either
  45. *                                        : I2C or SPI writing function
  46. * Input         : Register Address, Data to be written
  47. * Output                        : None
  48. * Return                        : None
  49. *******************************************************************************/
  50. status_t LIS3DSH_ACC_WriteReg(void *handle, u8_t Reg, u8_t *Bufp, u16_t len)
  51. {
  52.    
  53.   //To be completed with either I2c or SPI writing function
  54.   //i.e.: SPI_Mems_Write_Reg(Reg, Data);
  55.   //I2Cx_Write(Bufp, LIS3DSH_ACC_I2C_ADDRESS_HIGH, Reg, len); //[Example]
  56.   return MEMS_SUCCESS;
  57. }

  58. /**************** Base Function  *******************/

  59. /*******************************************************************************
  60. * Function Name  : GetWHO_AM_I
  61. * Description    : Read identification code by WHO_AM_I register
  62. * Input          : Char to empty by Device identification Value
  63. * Output         : None
  64. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  65. *******************************************************************************/
  66. status_t LIS3DSH_ACC_GetWHO_AM_I(void *handle, u8_t* val){
  67.   
  68.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_WHO_AM_I, val, 1) )
  69.     return MEMS_ERROR;
  70.   
  71.   return MEMS_SUCCESS;
  72. }


  73. /*******************************************************************************
  74. * Function Name  : GetOUT_T
  75. * Description    : Read temperature register 1LSB/deg (00h = 25degC)
  76. * Input          : Char to empty by temperature value (8bit 2's complement)
  77. * Output         : None
  78. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  79. *******************************************************************************/
  80. status_t LIS3DSH_ACC_GetOUT_T(void *handle, u8_t* val){
  81.    if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_T, val, 1) )
  82.     return MEMS_ERROR;
  83.   
  84.   return MEMS_SUCCESS;
  85. }


  86. /*******************************************************************************
  87. * Function Name  : SetODR
  88. * Description    : Sets Output Data Rate
  89. * Input          : Output Data Rate typedef
  90. * Output         : None
  91. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  92. *******************************************************************************/
  93. status_t LIS3DSH_ACC_SetODR(void *handle, LIS3DSH_ACC_ODR_t ov){
  94.   u8_t value;

  95.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL4, &value, 1) )
  96.     return MEMS_ERROR;

  97.   value &= 0x0f;
  98.   value |= ov<<LIS3DSH_ACC_ODR_BIT;
  99.    
  100.     if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL4, &value, 1) )
  101.     return MEMS_ERROR;
  102.   
  103.   return MEMS_SUCCESS;
  104. }


  105. /*******************************************************************************
  106. * Function Name  : SetAxis
  107. * Description    : Enable/Disable Acc. Axis
  108. * Input          : X_ENABLE/X_DISABLE | Y_ENABLE/Y_DISABLE | Z_ENABLE/Z_DISABLE
  109. * Output         : None
  110. * Note           : You MUST use all input variable in the argument
  111. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  112. *******************************************************************************/
  113. status_t LIS3DSH_ACC_SetAxis(void *handle, LIS3DSH_ACC_Axis_t axis) {
  114.   u8_t value;
  115.   
  116.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL4, &value, 1) )
  117.     return MEMS_ERROR;
  118.   value &= 0xF8;
  119.   value |= (0x07 & axis);
  120.    
  121.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL4, &value, 1) )
  122.     return MEMS_ERROR;   
  123.   
  124.   return MEMS_SUCCESS;
  125. }


  126. /*******************************************************************************
  127. * Function Name  : SetFullScale
  128. * Description    : Set FullScale by typedef definition
  129. * Input          : FULLSCALE_2/FULLSCALE_4/FULLSCALE_8/FULLSCALE_16
  130. * Output         : None
  131. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  132. *******************************************************************************/
  133. status_t LIS3DSH_ACC_SetFullScale(void *handle, LIS3DSH_ACC_Fullscale_t fs) {
  134.   u8_t value;
  135.   
  136.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  137.     return MEMS_ERROR;
  138.                   
  139.   value &= 0xC7;       
  140.   value |= (fs<<LIS3DSH_ACC_FSCALE);
  141.   
  142.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  143.     return MEMS_ERROR;
  144.   
  145.   return MEMS_SUCCESS;
  146. }


  147. /*******************************************************************************
  148. * Function Name  : SetBDU
  149. * Description    : Enable/Disable Block Data Update Functionality
  150. * Input          : ENABLE/DISABLE
  151. * Output         : None
  152. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  153. *******************************************************************************/
  154. status_t LIS3DSH_ACC_SetBDU(void *handle, LIS3DSH_ACC_State_t bdu) {
  155.   u8_t value;
  156.   
  157.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL4, &value, 1) )
  158.     return MEMS_ERROR;

  159.   value &= 0xF7;
  160.   value |= (bdu<<LIS3DSH_ACC_BDU);

  161.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL4, &value, 1) )
  162.     return MEMS_ERROR;

  163.   return MEMS_SUCCESS;
  164. }


  165. /*******************************************************************************
  166. * Function Name  : SetSelfTest
  167. * Description    : Set Self Test Modality
  168. * Input          : SELF_TEST_NORMAL/SELF_TEST_POSITIVE/SELF_TEST_NEGATIVE...
  169. * Output         : None
  170. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  171. *******************************************************************************/
  172. status_t LIS3DSH_ACC_SetSelfTest(void *handle, LIS3DSH_ACC_SelfTest_t st) {
  173.   u8_t value;
  174.   
  175.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  176.     return MEMS_ERROR;
  177.                   
  178.   value &= 0xF9;
  179.   value |= (st<<LIS3DSH_ACC_ST);
  180.   
  181.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  182.     return MEMS_ERROR;
  183.   
  184.   return MEMS_SUCCESS;
  185. }


  186. /*******************************************************************************
  187. * Function Name  : BandWidth
  188. * Description    : Set BandWidth filter by typedef definition
  189. * Input          : BANDWIDTH_1/BANDWIDTH_2/BANDWIDTH_3...
  190. * Output         : None
  191. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  192. *******************************************************************************/
  193. status_t LIS3DSH_ACC_BandWidth(void *handle, LIS3DSH_ACC_BandWidth_t bw) {
  194.   u8_t value;
  195.   
  196.   bw &= 0x03;
  197.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  198.     return MEMS_ERROR;
  199.                   
  200.   value &= 0x3F;
  201.   value |= (bw<<LIS3DSH_ACC_BW);
  202.   
  203.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  204.     return MEMS_ERROR;
  205.   
  206.   return MEMS_SUCCESS;
  207. }


  208. /*******************************************************************************
  209. * Function Name  : Int1Enable
  210. * Description    : Set Interrupt1 Enable-Disable
  211. * Input          : MEMS_ENABLE/MEMS_DISABLE
  212. * Output         : None
  213. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  214. *******************************************************************************/
  215. status_t LIS3DSH_ACC_Int1Enable(void *handle, LIS3DSH_ACC_State_t conf) {
  216.   u8_t value;
  217.   
  218.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  219.     return MEMS_ERROR;
  220.                   
  221.   value &= 0xF7;
  222.   value |= (conf<<LIS3DSH_ACC_INT1_EN);
  223.   
  224.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  225.     return MEMS_ERROR;
  226.   
  227.   return MEMS_SUCCESS;
  228. }


  229. /*******************************************************************************
  230. * Function Name  : Int2Enable
  231. * Description    : Set Interrupt2 Enable-Disable
  232. * Input          : MEMS_ENABLE/MEMS_DISABLE
  233. * Output         : None
  234. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  235. *******************************************************************************/
  236. status_t LIS3DSH_ACC_Int2Enable(void *handle, LIS3DSH_ACC_State_t conf) {
  237.   u8_t value;
  238.   
  239.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  240.     return MEMS_ERROR;
  241.                   
  242.   value &= 0xEF;
  243.   value |= (conf<<LIS3DSH_ACC_INT2_EN);
  244.   
  245.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  246.     return MEMS_ERROR;
  247.   
  248.   return MEMS_SUCCESS;
  249. }

  250.                  
  251. /*******************************************************************************
  252. * Function Name  : IntLatchEnable
  253. * Description    : Enable Interrupt Latching function
  254. * Input          : MEMS_ENABLE/MEMS_DISABLE
  255. * Output         : None
  256. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  257. *******************************************************************************/
  258. status_t LIS3DSH_ACC_IntLatchEnable(void *handle, LIS3DSH_ACC_State_t latch) {
  259.   u8_t value;
  260.   
  261.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  262.     return MEMS_ERROR;
  263.                   
  264.   value &= 0xDF;
  265.   value |= (latch<<LIS3DSH_ACC_IEL);
  266.   
  267.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  268.     return MEMS_ERROR;
  269.   
  270.   return MEMS_SUCCESS;
  271. }


  272. /*******************************************************************************
  273. * Function Name  : IntSignPol
  274. * Description    : Interrupt Polarity
  275. * Input          : POL_HIGH/POL_LOW
  276. * Output         : None
  277. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  278. *******************************************************************************/
  279. status_t LIS3DSH_ACC_IntSignPol(void *handle, LIS3DSH_ACC_Polarity_t pol) {
  280.   u8_t value;
  281.   
  282.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  283.     return MEMS_ERROR;
  284.                   
  285.   value &= 0xDF;
  286.   value |= (pol<<LIS3DSH_ACC_IEA);
  287.   
  288.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  289.     return MEMS_ERROR;
  290.   
  291.   return MEMS_SUCCESS;
  292. }


  293. /*******************************************************************************
  294. * Function Name  : DataReadyInt
  295. * Description    : Data ready connect to interrupt 1 Enable
  296. * Input          : MEMS_ENABLE/MEMS_DISABLE
  297. * Output         : None
  298. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  299. *******************************************************************************/
  300. status_t LIS3DSH_ACC_DataReadyInt(void *handle, LIS3DSH_ACC_State_t drdy) {
  301.   u8_t value;
  302.   
  303.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  304.     return MEMS_ERROR;
  305.                   
  306.   value &= 0x7F;
  307.   value |= (drdy<<LIS3DSH_ACC_DR_EN);
  308.   
  309.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  310.     return MEMS_ERROR;
  311.   
  312.   return MEMS_SUCCESS;
  313. }


  314. /*******************************************************************************
  315. * Function Name  : ReBootEnable
  316. * Description    : Force Reboot
  317. * Input          : MEMS_ENABLE/MEMS_DISABLE
  318. * Output         : None
  319. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  320. *******************************************************************************/
  321. status_t LIS3DSH_ACC_ReBootEnable(void *handle, LIS3DSH_ACC_State_t boot) {
  322.   u8_t value;
  323.   
  324.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  325.     return MEMS_ERROR;
  326.                   
  327.   value &= 0x7F;
  328.   value |= (boot<<LIS3DSH_ACC_BOOT);
  329.   
  330.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  331.     return MEMS_ERROR;
  332.   
  333.   return MEMS_SUCCESS;
  334. }


  335. /*******************************************************************************
  336. * Function Name  : FIFOEnable
  337. * Description    : FIFO enable/disable
  338. * Input          : MEMS_ENABLE/MEMS_DISABLE, n max sample in FIFO (must be < 30)
  339. * Output         : None
  340. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  341. *******************************************************************************/
  342. status_t LIS3DSH_ACC_FIFOEnable(void *handle, LIS3DSH_ACC_State_t fifo, u8_t nMax) {
  343.   u8_t value;
  344.   
  345.   //check n max of sample in FIFO
  346.   if(nMax > 30) return MEMS_ERROR;
  347.   
  348.   //only stream mode fifo
  349.   if(! LIS3DSH_ACC_FIFOMode(handle, LIS3DSH_ACC_FIFO_STREAM_MODE))
  350.     return MEMS_ERROR;  

  351.   //set WTM > n sample in FIFO
  352.   if(! LIS3DSH_ACC_SetWaterMark(handle, nMax))
  353.     return MEMS_ERROR;
  354.   
  355.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  356.     return MEMS_ERROR;
  357.                   
  358.   value &= 0xBF;
  359.   value |= (fifo<<LIS3DSH_ACC_FIFO_EN);
  360.   
  361.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  362.     return MEMS_ERROR;
  363.   
  364.   return MEMS_SUCCESS;
  365. }


  366. /*******************************************************************************
  367. * Function Name  : FIFOMode
  368. * Description    : Sets FIFO Modality
  369. * Input          : FIFO_BYPASS_MODE, FIFO_MODE...
  370. * Output         : None
  371. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  372. *******************************************************************************/
  373. status_t LIS3DSH_ACC_FIFOMode(void *handle, LIS3DSH_ACC_FifoMode_t fm) {
  374.   u8_t value;           
  375.   
  376.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_FIFO_CTRL, &value, 1) )
  377.       return MEMS_ERROR;
  378.    
  379.   value &= 0x1f;
  380.   value |= (fm<<LIS3DSH_ACC_FMODE);                  
  381.    
  382.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_FIFO_CTRL, &value, 1) )
  383.       return MEMS_ERROR;
  384.    
  385.   return MEMS_SUCCESS;
  386. }      


  387. /*******************************************************************************
  388. * Function Name  : SetWaterMark
  389. * Description    : Sets Watermark Value
  390. * Input          : Watermark = [0,31]
  391. * Output         : None
  392. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  393. *******************************************************************************/
  394. status_t LIS3DSH_ACC_SetWaterMark(void *handle, u8_t wtm) {
  395.   u8_t value;
  396.   
  397.   if(wtm > 31)
  398.     return MEMS_ERROR;  
  399.   
  400.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_FIFO_CTRL, &value, 1) )
  401.     return MEMS_ERROR;
  402.                   
  403.   value &= 0xE0;
  404.   value |= wtm;
  405.   
  406.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_FIFO_CTRL, &value, 1) )
  407.     return MEMS_ERROR;
  408.   
  409.   return MEMS_SUCCESS;
  410. }


  411. /*******************************************************************************
  412. * Function Name  : AddIncEnable
  413. * Description    : Register address increment (during multiple byte access) enable/disable
  414. * Input          : MEMS_ENABLE/MEMS_DISABLE
  415. * Output         : None
  416. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  417. *******************************************************************************/
  418. status_t LIS3DSH_ACC_AddIncEnable(void *handle, LIS3DSH_ACC_State_t addinc) {
  419.   u8_t value;
  420.   
  421.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  422.     return MEMS_ERROR;
  423.                   
  424.   value &= 0xEF;
  425.   value |= (addinc<<LIS3DSH_ACC_ADD_INC);
  426.   
  427.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  428.     return MEMS_ERROR;
  429.   
  430.   return MEMS_SUCCESS;
  431. }


  432. /*******************************************************************************
  433. * Function Name  : FifoEmptyInt1
  434. * Description    : FIFO empty indication on INT1 enable/disable
  435. * Input          : MEMS_ENABLE/MEMS_DISABLE
  436. * Output         : None
  437. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  438. *******************************************************************************/
  439. status_t LIS3DSH_ACC_FifoEmptyInt1(void *handle, LIS3DSH_ACC_State_t empty) {
  440.   u8_t value;
  441.   
  442.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  443.     return MEMS_ERROR;
  444.                   
  445.   value &= 0xF7;
  446.   value |= (empty<<LIS3DSH_ACC_I1_EMPTY);
  447.   
  448.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  449.     return MEMS_ERROR;
  450.   
  451.   return MEMS_SUCCESS;
  452. }


  453. /*******************************************************************************
  454. * Function Name  : FifoOvrInt1
  455. * Description    : FIFO Overrun interrupt on INT1 enable/disable
  456. * Input          : MEMS_ENABLE/MEMS_DISABLE
  457. * Output         : None
  458. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  459. *******************************************************************************/
  460. status_t LIS3DSH_ACC_FifoOvrInt1(void *handle, LIS3DSH_ACC_State_t overrun) {
  461.   u8_t value;
  462.   
  463.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  464.     return MEMS_ERROR;
  465.                   
  466.   value &= 0xFD;
  467.   value |= (overrun<<LIS3DSH_ACC_I1_OVERRUN);
  468.   
  469.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  470.     return MEMS_ERROR;
  471.   
  472.   return MEMS_SUCCESS;
  473. }


  474. /*******************************************************************************
  475. * Function Name  : BootInt2
  476. * Description    : Boot Interrupt on INT2 enable/disable
  477. * Input          : MEMS_ENABLE/MEMS_DISABLE
  478. * Output         : None
  479. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  480. *******************************************************************************/
  481. status_t LIS3DSH_ACC_BootInt2(void *handle, LIS3DSH_ACC_State_t booti2) {
  482.   u8_t value;
  483.   
  484.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  485.     return MEMS_ERROR;
  486.                   
  487.   value &= 0xFE;
  488.   value |= (booti2<<LIS3DSH_ACC_I2_BOOT);
  489.   
  490.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL6, &value, 1) )
  491.     return MEMS_ERROR;
  492.   
  493.   return MEMS_SUCCESS;
  494. }


  495. /*******************************************************************************
  496. * Function Name  : VectFiltEnable
  497. * Description    : Vector Filter Enable-Disable
  498. * Input          : MEMS_ENABLE/MEMS_DISABLE
  499. * Output         : None
  500. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  501. *******************************************************************************/
  502. status_t LIS3DSH_ACC_VectFiltEnable(void *handle, LIS3DSH_ACC_State_t vfe) {
  503.   u8_t value;
  504.   
  505.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  506.     return MEMS_ERROR;
  507.                   
  508.   value &= 0x7F;
  509.   value |= (vfe<<LIS3DSH_ACC_VFILT);
  510.   
  511.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  512.     return MEMS_ERROR;
  513.   
  514.   return MEMS_SUCCESS;
  515. }


  516. /*******************************************************************************
  517. * Function Name  : SoftReset
  518. * Description    : Soft Reset BIT Enable-Disable
  519. * Input          : MEMS_ENABLE/MEMS_DISABLE
  520. * Output         : None
  521. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  522. *******************************************************************************/
  523. status_t LIS3DSH_ACC_SoftReset(void *handle, LIS3DSH_ACC_State_t strt) {
  524.   u8_t value;
  525.   
  526.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  527.     return MEMS_ERROR;
  528.                   
  529.   value &= 0xFE;
  530.   value |= (strt<<LIS3DSH_ACC_STRT);
  531.   
  532.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL3, &value, 1) )
  533.     return MEMS_ERROR;
  534.   
  535.   return MEMS_SUCCESS;
  536. }   


  537. /*******************************************************************************
  538. * Function Name  : SetOFFSET
  539. * Description    : Set offset Value
  540. * Input          : AXIS: SET_AXIS_X/SET_AXSIS_Y/SET_AXIS_Z, Offest value = [0,255]
  541. * Output         : None
  542. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  543. *******************************************************************************/
  544. status_t LIS3DSH_ACC_SetOFFSET(void *handle, LIS3DSH_ACC_SET_AXIS_t axis, u8_t val) {
  545.   u8_t reg=0;
  546.   
  547.   if(!((axis==LIS3DSH_ACC_SET_AXIS_X)||(axis==LIS3DSH_ACC_SET_AXIS_Y)||(axis==LIS3DSH_ACC_SET_AXIS_Z)))
  548.     return MEMS_ERROR;
  549.   
  550.   switch(axis){
  551.           case LIS3DSH_ACC_SET_AXIS_X: reg=LIS3DSH_ACC_OFF_X; break;
  552.           case LIS3DSH_ACC_SET_AXIS_Y: reg=LIS3DSH_ACC_OFF_Y; break;
  553.           case LIS3DSH_ACC_SET_AXIS_Z: reg=LIS3DSH_ACC_OFF_Z; break;
  554.   }  
  555.   
  556.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &val, 1) )
  557.     return MEMS_ERROR;
  558.   
  559.   return MEMS_SUCCESS;
  560. }


  561. /*******************************************************************************
  562. * Function Name  : SetCS
  563. * Description    : Set Constant Shift Value
  564. * Input          : AXIS: SET_AXIS_X/SET_AXSIS_Y/SET_AXIS_Z, Constant shift value = [0,255]
  565. * Output         : None
  566. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  567. *******************************************************************************/
  568. status_t LIS3DSH_ACC_SetCS(void *handle, LIS3DSH_ACC_SET_AXIS_t axis, u8_t val) {
  569.   u8_t reg=0;
  570.   
  571.   if(!((axis==LIS3DSH_ACC_SET_AXIS_X)||(axis==LIS3DSH_ACC_SET_AXIS_Y)||(axis==LIS3DSH_ACC_SET_AXIS_Z)))
  572.     return MEMS_ERROR;
  573.   
  574.   switch(axis){
  575.           case LIS3DSH_ACC_SET_AXIS_X: reg=LIS3DSH_ACC_CS_X; break;
  576.           case LIS3DSH_ACC_SET_AXIS_Y: reg=LIS3DSH_ACC_CS_Y; break;
  577.           case LIS3DSH_ACC_SET_AXIS_Z: reg=LIS3DSH_ACC_CS_Z; break;
  578.   }  
  579.   
  580.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &val, 1) )
  581.     return MEMS_ERROR;
  582.   
  583.   return MEMS_SUCCESS;
  584. }


  585. /*******************************************************************************
  586. * Function Name  : SetLC
  587. * Description    : Set Long Counter Register Value
  588. * Input          : Long Counter 16Bit value
  589. * Output         : None
  590. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  591. *******************************************************************************/
  592. status_t LIS3DSH_ACC_SetLC(void *handle, u16_t val) {
  593.   u8_t val_L=0;
  594.   u8_t val_H=0;
  595.   
  596.   val_L = (u8_t) (val & 0x00FF);
  597.   val_H = (u8_t) ((val & 0xFF00)>>8);
  598.   
  599.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_LC_L, &val_L, 1) )
  600.     return MEMS_ERROR;
  601.    
  602.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_LC_H, &val_H, 1) )
  603.     return MEMS_ERROR;
  604.   
  605.   return MEMS_SUCCESS;
  606. }


  607. /*******************************************************************************
  608. * Function Name  : GetLC
  609. * Description    : Get Long Counter Register Value
  610. * Input          : 16Bit Variable to empty by Counter value
  611. * Output         : None
  612. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  613. *******************************************************************************/
  614. status_t LIS3DSH_ACC_GetLC(void *handle, i16_t* val) {
  615.   u8_t val_L=0;
  616.   u8_t val_H=0;

  617.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_LC_L, &val_L, 1) )
  618.     return MEMS_ERROR;
  619.    
  620.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_LC_H, &val_H, 1) )
  621.     return MEMS_ERROR;

  622.   *val = (i16_t)((val_H<<8) + val_L);
  623.   
  624.   return MEMS_SUCCESS;
  625. }


  626. /*******************************************************************************
  627. * Function Name  : SetVectorCoeff
  628. * Description    : Set Vector Coefficient Value for Differential filter
  629. * Input          : SET_VFC_1/SET_VFC_2/SET_VFC_3, Coefficient value = [0,255]
  630. * Output         : None
  631. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  632. *******************************************************************************/
  633. status_t LIS3DSH_ACC_SetVectorCoeff(void *handle, LIS3DSH_ACC_SET_VFC_t vfc, u8_t val) {
  634.   u8_t reg=0;
  635.   
  636.   if(!((vfc==LIS3DSH_ACC_SET_VFC_1)||(vfc==LIS3DSH_ACC_SET_VFC_2)||(vfc==LIS3DSH_ACC_SET_VFC_3)||(vfc==LIS3DSH_ACC_SET_VFC_4)))
  637.     return MEMS_ERROR;
  638.   
  639.   switch(vfc){
  640.           case LIS3DSH_ACC_SET_VFC_1: reg=LIS3DSH_ACC_VFC_1; break;
  641.           case LIS3DSH_ACC_SET_VFC_2: reg=LIS3DSH_ACC_VFC_2; break;
  642.         case LIS3DSH_ACC_SET_VFC_3: reg=LIS3DSH_ACC_VFC_3; break;
  643.           case LIS3DSH_ACC_SET_VFC_4: reg=LIS3DSH_ACC_VFC_4; break;
  644.   }  
  645.   
  646.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &val, 1) )
  647.     return MEMS_ERROR;
  648.   
  649.   return MEMS_SUCCESS;
  650. }


  651. /*******************************************************************************
  652. * Function Name  : GetVectorCoeff
  653. * Description    : Get Vector Coefficient Value for Differential filter
  654. * Input          : SET_VFC_1/SET_VFC_2/SET_VFC_3, variable to empty
  655. * Output         : None
  656. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  657. *******************************************************************************/
  658. status_t LIS3DSH_ACC_GetVectorCoeff(void *handle, LIS3DSH_ACC_SET_VFC_t vfc, u8_t* val) {
  659.   u8_t reg;
  660.   
  661.   if(!((vfc==LIS3DSH_ACC_SET_VFC_1)||(vfc==LIS3DSH_ACC_SET_VFC_2)||(vfc==LIS3DSH_ACC_SET_VFC_3)||(vfc==LIS3DSH_ACC_SET_VFC_4)))
  662.     return MEMS_ERROR;
  663.   
  664.   switch(vfc){
  665.   case LIS3DSH_ACC_SET_VFC_1: reg = LIS3DSH_ACC_VFC_1; break;
  666.   case LIS3DSH_ACC_SET_VFC_2: reg = LIS3DSH_ACC_VFC_2; break;
  667.   case LIS3DSH_ACC_SET_VFC_3: reg = LIS3DSH_ACC_VFC_3; break;
  668.   case LIS3DSH_ACC_SET_VFC_4: reg = LIS3DSH_ACC_VFC_4; break;
  669.   }  
  670.   
  671.   if( !LIS3DSH_ACC_ReadReg(handle, reg, val, 1) )
  672.     return MEMS_ERROR;
  673.   
  674.   return MEMS_SUCCESS;
  675. }

  676. /*******************************************************************************
  677. * Function Name  : SetThrs3
  678. * Description    : set Threshold3 Coefficient Value
  679. * Input          : Value of threshold [0,255]
  680. * Output         : None
  681. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  682. *******************************************************************************/
  683. status_t LIS3DSH_ACC_SetThrs3(void *handle, u8_t val) {
  684.   
  685.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_THRS3, &val, 1) )
  686.     return MEMS_ERROR;
  687.   
  688.   return MEMS_SUCCESS;
  689. }


  690. /*******************************************************************************
  691. * Function Name  : GetThrs3
  692. * Description    : Get Threshold3 Coefficient Value
  693. * Input          : Variable to empty
  694. * Output         : None
  695. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  696. *******************************************************************************/
  697. status_t LIS3DSH_ACC_GetThrs3(void *handle, u8_t* val) {
  698.   
  699.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_THRS3, val, 1) )
  700.     return MEMS_ERROR;
  701.   
  702.   return MEMS_SUCCESS;
  703. }


  704. /*******************************************************************************
  705. * Function Name  : GetThrsSM
  706. * Description    : Get Threshold 1 or 2 by SM1 or SM2
  707. * Input          : SM1/SM2, THRS1/THRS2, Variable to empty
  708. * Output         : None
  709. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  710. *******************************************************************************/
  711. status_t LIS3DSH_ACC_GetThrsSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_THRS_t thrs, u8_t* val) {
  712.   u8_t reg=0;
  713.   
  714.   switch(thrs){
  715.   case LIS3DSH_ACC_THRS_1:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_THRS1_1;
  716.                   else                 reg = LIS3DSH_ACC_THRS1_2;
  717.                 break;
  718.   case LIS3DSH_ACC_THRS_2:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_THRS2_1;
  719.                   else                 reg = LIS3DSH_ACC_THRS2_2;
  720.                 break;
  721.   }  
  722.   
  723.   if( !LIS3DSH_ACC_ReadReg(handle, reg, val, 1) )
  724.     return MEMS_ERROR;
  725.    
  726.   return MEMS_SUCCESS;
  727. }


  728. /*******************************************************************************
  729. * Function Name  : SetThrsSM
  730. * Description    : Set Threshold 1 or 2 for SM1 or SM2
  731. * Input          : SM1/SM2, THRS1/THRS2, Threshold Value [0,255]
  732. * Output         : None
  733. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  734. *******************************************************************************/
  735. status_t LIS3DSH_ACC_SetThrsSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_THRS_t thrs, u8_t val) {
  736.   u8_t reg=0;
  737.   
  738.   switch(thrs){
  739.   case LIS3DSH_ACC_THRS_1:  if(sm==LIS3DSH_ACC_SM1) reg = LIS3DSH_ACC_THRS1_1;
  740.                   else reg = LIS3DSH_ACC_THRS1_2;
  741.                 break;
  742.   case LIS3DSH_ACC_THRS_2:  if(sm==LIS3DSH_ACC_SM1) reg = LIS3DSH_ACC_THRS2_1;
  743.                   else reg = LIS3DSH_ACC_THRS2_2;
  744.                 break;
  745.   }  
  746.   
  747.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &val, 1) )
  748.     return MEMS_ERROR;
  749.    
  750.   return MEMS_SUCCESS;
  751. }


  752. /*******************************************************************************
  753. * Function Name  : SetTimerSM
  754. * Description    : Set Timer 1(16bit),2(16bit),3(8bit),4(8bit) for SM1 or SM2
  755. * Input          : SM1/SM2, TIM1/TIM2..., Timer Value (8bit or 16bit)
  756. * Output         : None
  757. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  758. *******************************************************************************/
  759. status_t LIS3DSH_ACC_SetTimerSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_TIM_t timer, u16_t val) {
  760.   u8_t reg=0;
  761.   u8_t val_L=0;
  762.   u8_t val_H=0;
  763.   
  764.   switch(timer){
  765.   case LIS3DSH_ACC_TIM_1:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_TIM1_1_L;
  766.                   else                 reg = LIS3DSH_ACC_TIM1_2_L;
  767.                 break;
  768.   case LIS3DSH_ACC_TIM_2:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_TIM2_1_L;
  769.                   else                 reg = LIS3DSH_ACC_TIM2_2_L;
  770.                 break;
  771.   case LIS3DSH_ACC_TIM_3:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_TIM3_1;
  772.                   else                 reg = LIS3DSH_ACC_TIM3_2;
  773.                 break;
  774.   case LIS3DSH_ACC_TIM_4:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_TIM4_1;
  775.                   else                 reg = LIS3DSH_ACC_TIM4_2;
  776.                 break;               
  777.   }
  778.   //for 8bit register
  779.   if((timer==LIS3DSH_ACC_TIM_3)||(timer==LIS3DSH_ACC_TIM_4)){
  780.     val_L = (u8_t) val;
  781.     if( !LIS3DSH_ACC_WriteReg(handle, reg, &val_L, 1) )
  782.             return MEMS_ERROR;
  783.   }
  784.   //for 16bit register
  785.   else{
  786.   val_L = (u8_t)  val;
  787.   val_H = (u8_t) (val>>8);  
  788.    
  789.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &val_L, 1) )
  790.     return MEMS_ERROR;
  791.   if( !LIS3DSH_ACC_WriteReg(handle, reg+1, &val_H, 1) )
  792.     return MEMS_ERROR;   
  793.   }
  794.   
  795.   return MEMS_SUCCESS;
  796. }


  797. /*******************************************************************************
  798. * Function Name  : SetMaskSM
  799. * Description    : Set Mask A or B for SM1 or SM2
  800. * Input          : SM1/SM2, MASK_A/MASK_B, Mask Value [0,255]
  801. * Output         : None
  802. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  803. *******************************************************************************/
  804. status_t LIS3DSH_ACC_SetMaskSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_MASK_t mask, u8_t val) {
  805.   u8_t reg=0;
  806.   
  807.   switch(mask){
  808.   case LIS3DSH_ACC_MASK_A:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_MASKA_1;
  809.                   else                 reg = LIS3DSH_ACC_MASKA_2;
  810.                 break;
  811.   case LIS3DSH_ACC_MASK_B:  if(sm==LIS3DSH_ACC_SM1)         reg = LIS3DSH_ACC_MASKB_1;
  812.                   else                 reg = LIS3DSH_ACC_MASKB_2;
  813.                 break;
  814.   }  
  815.   
  816.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &val, 1) )
  817.     return MEMS_ERROR;
  818.    
  819.   return MEMS_SUCCESS;
  820. }


  821. /*******************************************************************************
  822. * Function Name  : GetProgPointSM
  823. * Description    : Get Program pointer for SM1 or SM2
  824. * Input          : Byte to empty by Program pointer value (4bit)
  825. * Output         : None
  826. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  827. *******************************************************************************/
  828. status_t LIS3DSH_ACC_GetProgPointSM(void *handle, LIS3DSH_ACC_SM_t sm, u8_t* val) {
  829.   u8_t reg=0;
  830.   
  831.   switch(sm){
  832.   case LIS3DSH_ACC_SM1 : reg = LIS3DSH_ACC_PR1; break;
  833.   case LIS3DSH_ACC_SM2 : reg = LIS3DSH_ACC_PR2; break;
  834.   }
  835.   
  836.   if( !LIS3DSH_ACC_ReadReg(handle, reg, val, 1) )
  837.     return MEMS_ERROR;

  838.   *val = (*val & 0xF0) >> 4;
  839.   
  840.   return MEMS_SUCCESS;
  841. }


  842. /*******************************************************************************
  843. * Function Name  : GetResetPointSM
  844. * Description    : Get Reset pointer for SM1 or SM2
  845. * Input          : Byte to empty by Reset pointer value (4bit)
  846. * Output         : None
  847. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  848. *******************************************************************************/
  849. status_t LIS3DSH_ACC_GetResetPointSM(void *handle, LIS3DSH_ACC_SM_t sm, u8_t* val) {
  850.   u8_t reg=0;
  851.   
  852.   switch(sm){
  853.   case LIS3DSH_ACC_SM1 : reg = LIS3DSH_ACC_PR1; break;
  854.   case LIS3DSH_ACC_SM2 : reg = LIS3DSH_ACC_PR2; break;
  855.   }
  856.   
  857.   if( !LIS3DSH_ACC_ReadReg(handle, reg, val, 1) )
  858.     return MEMS_ERROR;

  859.   *val = (*val & 0x0F);
  860.   
  861.   return MEMS_SUCCESS;
  862. }


  863. /*******************************************************************************
  864. * Function Name  : GetTCSM
  865. * Description    : Get 16bit general Timer Value for SM1 or SM2
  866. * Input          : SM1/SM2, 16bit Variable to empty by timer value
  867. * Output         : None
  868. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  869. *******************************************************************************/
  870. status_t LIS3DSH_ACC_GetTCSM(void *handle, LIS3DSH_ACC_SM_t sm, u16_t* val) {
  871.   u8_t val_L=0;
  872.   u8_t val_H=0;
  873.   u8_t reg=0;
  874.   
  875.   switch(sm){
  876.   case LIS3DSH_ACC_SM1: reg = LIS3DSH_ACC_TC1_L;  break;
  877.   case LIS3DSH_ACC_SM2: reg = LIS3DSH_ACC_TC2_L;  break;  
  878.   }
  879.   
  880.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &val_L, 1) )
  881.     return MEMS_ERROR;
  882.    
  883.   if( !LIS3DSH_ACC_ReadReg(handle, reg+1, &val_H, 1) )
  884.     return MEMS_ERROR;

  885.   *val = (u16_t)((val_H<<8) + val_L);
  886.   
  887.   return MEMS_SUCCESS;
  888. }


  889. /*******************************************************************************
  890. * Function Name  : GetOutSBitSM
  891. * Description    : Read the output flags for interrupt by SM1 or SM2
  892. * Input          : Out interrupt Bit to read (P_X/P_Y/N_Z/N_V....)
  893. * Output         : None
  894. * Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
  895. *******************************************************************************/
  896. status_t LIS3DSH_ACC_GetOutSBitSM(void *handle, LIS3DSH_ACC_SM_t sm, u8_t FLAG_INT_OUT) {
  897.   u8_t value;
  898.   u8_t reg;

  899.   switch(sm){
  900.   case LIS3DSH_ACC_SM1: reg = LIS3DSH_ACC_OUTS1;  break;
  901.   case LIS3DSH_ACC_SM2: reg = LIS3DSH_ACC_OUTS2;  break;  
  902.   }
  903.   
  904.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  905.       return MEMS_ERROR;

  906.   switch (FLAG_INT_OUT){
  907.   case LIS3DSH_ACC_F_P_X : if(value & LIS3DSH_ACC_F_P_X) return MEMS_SUCCESS;
  908.              else                  return MEMS_ERROR;
  909.   case LIS3DSH_ACC_F_N_X : if(value & LIS3DSH_ACC_F_N_X) return MEMS_SUCCESS;
  910.              else                  return MEMS_ERROR;
  911.   case LIS3DSH_ACC_F_P_Y : if(value & LIS3DSH_ACC_F_P_Y) return MEMS_SUCCESS;
  912.              else                  return MEMS_ERROR;
  913.   case LIS3DSH_ACC_F_N_Y : if(value & LIS3DSH_ACC_F_N_Y) return MEMS_SUCCESS;
  914.              else                  return MEMS_ERROR;
  915.   case LIS3DSH_ACC_F_P_Z : if(value & LIS3DSH_ACC_F_P_Z) return MEMS_SUCCESS;
  916.              else                  return MEMS_ERROR;
  917.   case LIS3DSH_ACC_F_N_Z : if(value & LIS3DSH_ACC_F_N_Z) return MEMS_SUCCESS;
  918.              else                  return MEMS_ERROR;
  919.   case LIS3DSH_ACC_F_P_V : if(value & LIS3DSH_ACC_F_P_V) return MEMS_SUCCESS;
  920.              else                  return MEMS_ERROR;
  921.   case LIS3DSH_ACC_F_N_V : if(value & LIS3DSH_ACC_F_N_V) return MEMS_SUCCESS;
  922.              else                  return MEMS_ERROR;     
  923.   }
  924.   
  925. return MEMS_ERROR;
  926. }
  927.   

  928. /*******************************************************************************
  929. * Function Name  : GetPeakSM
  930. * Description    : Read the Peak detection Register value by SM1 or SM2
  931. * Input          : SM1/SM2, Variable (8bit) to empty by Peak Register Value
  932. * Output         : None
  933. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  934. *******************************************************************************/
  935. status_t LIS3DSH_ACC_GetPeakSM(void *handle, LIS3DSH_ACC_SM_t sm, u8_t* val) {
  936.   u8_t reg;
  937.   
  938.   switch(sm){
  939.   case LIS3DSH_ACC_SM1: reg = LIS3DSH_ACC_PEAK1; break;
  940.   case LIS3DSH_ACC_SM2: reg = LIS3DSH_ACC_PEAK2; break;  
  941.   }
  942.   
  943.   if( !LIS3DSH_ACC_ReadReg(handle, reg, val, 1) )
  944.       return MEMS_ERROR;
  945.   
  946.   return MEMS_SUCCESS;  
  947. }


  948. /*******************************************************************************
  949. * Function Name  : GetDecimSM2
  950. * Description    : Read the Decimator counter Register value by SM2
  951. * Input          : Variable (8bit) to empty by Decimator counter Value
  952. * Output         : None
  953. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  954. *******************************************************************************/
  955. status_t LIS3DSH_ACC_GetDecimSM2(void *handle, u8_t* val) {
  956.   
  957.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_DES2, val, 1) )
  958.       return MEMS_ERROR;
  959.   
  960.   return MEMS_SUCCESS;  
  961. }


  962. /*******************************************************************************
  963. * Function Name  : SetIntPinSM
  964. * Description    : Set SMx Interrupt PIN routed to INT1 or INT2
  965. * Input          : SMx, MEMS_DISABLE/ENABLE  (MEMS_DISABLE = routed INT1)
  966. * Output         : None
  967. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  968. *******************************************************************************/
  969. status_t LIS3DSH_ACC_SetIntPinSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  970.   u8_t reg=0;
  971.   u8_t value=0;
  972.   
  973.   switch(sm){
  974.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_CNTL1; break;
  975.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_CNTL2; break;
  976.   }  
  977.   
  978.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  979.     return MEMS_ERROR;

  980.   value &= 0xF7;
  981.   value |= (state<<LIS3DSH_ACC_SM_PIN);   
  982.   
  983.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  984.     return MEMS_ERROR;
  985.   
  986.   return MEMS_SUCCESS;
  987. }


  988. /*******************************************************************************
  989. * Function Name  : SetIntEnaSM
  990. * Description    : Set SMx Interrupt Enable for SM1 or SM2
  991. * Input          : SMx, MEMS_DISABLE/ENABLE
  992. * Output         : None
  993. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  994. *******************************************************************************/
  995. status_t LIS3DSH_ACC_SetIntEnaSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  996.   u8_t reg=0;
  997.   u8_t value=0;
  998.   
  999.   switch(sm){
  1000.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_CNTL1; break;
  1001.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_CNTL2; break;
  1002.   }  
  1003.   
  1004.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1005.     return MEMS_ERROR;  
  1006.   
  1007.   value &= 0xFE;
  1008.   value |= (state<<LIS3DSH_ACC_SM_EN);  
  1009.   
  1010.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1011.     return MEMS_ERROR;
  1012.   
  1013.   return MEMS_SUCCESS;
  1014. }


  1015. /*******************************************************************************
  1016. * Function Name  : SetPeakDetSM
  1017. * Description    : Set SMx Peak Detection Enable
  1018. * Input          : SMx, MEMS_DISABLE/ENABLE
  1019. * Output         : None
  1020. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1021. *******************************************************************************/
  1022. status_t LIS3DSH_ACC_SetPeakDetSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  1023.   u8_t reg=0;   
  1024.   u8_t value;
  1025.   
  1026.   switch(sm){
  1027.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_SETT1; break;
  1028.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_SETT2; break;
  1029.   }  

  1030.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1031.     return MEMS_ERROR;
  1032.                   
  1033.   value &= 0x7F;
  1034.   value |= (state<<LIS3DSH_ACC_P_DET);
  1035.   
  1036.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1037.     return MEMS_ERROR;
  1038.   
  1039.   return MEMS_SUCCESS;
  1040. }


  1041. /*******************************************************************************
  1042. * Function Name  : SetThr3SaSM
  1043. * Description    : Set SMx threshold3 limit value for axis and sign mask reset (MASKB_x)
  1044. * Input          : SMx, MEMS_DISABLE/ENABLE
  1045. * Output         : None
  1046. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1047. *******************************************************************************/
  1048. status_t LIS3DSH_ACC_SetThr3SaSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  1049.   u8_t reg=0;   
  1050.   u8_t value;
  1051.   
  1052.   switch(sm){
  1053.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_SETT1; break;
  1054.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_SETT2; break;
  1055.   }  

  1056.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1057.     return MEMS_ERROR;
  1058.                   
  1059.   value &= 0xBF;
  1060.   value |= (state<<LIS3DSH_ACC_THR3_SA);
  1061.   
  1062.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1063.     return MEMS_ERROR;
  1064.   
  1065.   return MEMS_SUCCESS;
  1066. }


  1067. /*******************************************************************************
  1068. * Function Name  : SetThr3MaSM
  1069. * Description    : Set SMx threshold3 limit value for axis and sign mask reset (MASKA_x)
  1070. * Input          : SMx, MEMS_DISABLE/ENABLE
  1071. * Output         : None
  1072. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1073. *******************************************************************************/
  1074. status_t LIS3DSH_ACC_SetThr3MaSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  1075.   u8_t reg=0;   
  1076.   u8_t value;
  1077.   
  1078.   switch(sm){
  1079.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_SETT1; break;
  1080.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_SETT2; break;
  1081.   }  

  1082.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1083.     return MEMS_ERROR;
  1084.                   
  1085.   value &= 0xFB;
  1086.   value |= (state<<LIS3DSH_ACC_THR3_MA);
  1087.   
  1088.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1089.     return MEMS_ERROR;
  1090.   
  1091.   return MEMS_SUCCESS;
  1092. }


  1093. /*******************************************************************************
  1094. * Function Name  : SetAbsSM
  1095. * Description    : Set SMx absolute value enable
  1096. * Input          : SMx, MEMS_DISABLE/ENABLE
  1097. * Output         : None
  1098. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1099. *******************************************************************************/
  1100. status_t LIS3DSH_ACC_SetAbsSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  1101.   u8_t reg=0;   
  1102.   u8_t value;
  1103.   
  1104.   switch(sm){
  1105.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_SETT1; break;
  1106.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_SETT2; break;
  1107.   }  

  1108.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1109.     return MEMS_ERROR;
  1110.                   
  1111.   value &= 0xDF;
  1112.   value |= (state<<LIS3DSH_ACC_ABS);
  1113.   
  1114.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1115.     return MEMS_ERROR;
  1116.   
  1117.   return MEMS_SUCCESS;
  1118. }


  1119. /*******************************************************************************
  1120. * Function Name  : SetRTamSM
  1121. * Description    : Set SMx next condition validation flag
  1122. * Input          : SMx, MEMS_DISABLE/ENABLE
  1123. * Output         : None
  1124. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1125. *******************************************************************************/
  1126. status_t LIS3DSH_ACC_SetRTamSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  1127.   u8_t reg=0;   
  1128.   u8_t value;
  1129.   
  1130.   switch(sm){
  1131.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_SETT1; break;
  1132.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_SETT2; break;
  1133.   }  

  1134.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1135.     return MEMS_ERROR;
  1136.                   
  1137.   value &= 0xFD;
  1138.   value |= (state<<LIS3DSH_ACC_R_TAM);
  1139.   
  1140.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1141.     return MEMS_ERROR;
  1142.   
  1143.   return MEMS_SUCCESS;
  1144. }


  1145. /*******************************************************************************
  1146. * Function Name  : SetSitrSM
  1147. * Description    : Set SMx program flow can be modified by STOP and COUNT
  1148. * Input          : SMx, MEMS_DISABLE/ENABLE
  1149. * Output         : None
  1150. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1151. *******************************************************************************/
  1152. status_t LIS3DSH_ACC_SetSitrSM(void *handle, LIS3DSH_ACC_SM_t sm, LIS3DSH_ACC_State_t state) {
  1153.   u8_t reg=0;   
  1154.   u8_t value;
  1155.   
  1156.   switch(sm){
  1157.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_SETT1; break;
  1158.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_SETT2; break;
  1159.   }  

  1160.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &value, 1) )
  1161.     return MEMS_ERROR;
  1162.                   
  1163.   value &= 0xFE;
  1164.   value |= (state<<LIS3DSH_ACC_SITR);
  1165.   
  1166.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &value, 1) )
  1167.     return MEMS_ERROR;
  1168.   
  1169.   return MEMS_SUCCESS;

  1170. }


  1171. /*******************************************************************************
  1172. * Function Name  : SetHystSM
  1173. * Description    : Set Hysteresis for SM1 or SM2
  1174. * Input          : SM1/SM2, Hysteresis Value [0,7] (3bit)
  1175. * Output         : None
  1176. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1177. *******************************************************************************/
  1178. status_t LIS3DSH_ACC_SetHystSM(void *handle, LIS3DSH_ACC_SM_t  sm, u8_t val) {
  1179.   u8_t reg=0;
  1180.   u8_t read=0;
  1181.   
  1182.   switch(sm){
  1183.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_CNTL1; break;
  1184.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_CNTL2; break;
  1185.   }  
  1186.   
  1187.   if( !LIS3DSH_ACC_ReadReg(handle, reg, &read, 1) )
  1188.     return MEMS_ERROR;
  1189.   
  1190.   read &= 0x1F;
  1191.   read |= (val<<LIS3DSH_ACC_HYST);
  1192.   
  1193.   if( !LIS3DSH_ACC_WriteReg(handle, reg, &read, 1) )
  1194.     return MEMS_ERROR;
  1195.   
  1196.   return MEMS_SUCCESS;
  1197. }


  1198. /*******************************************************************************
  1199. * Function Name  : GetSatusReg
  1200. * Description    : Read the status register
  1201. * Input          : char to empty by Status Reg Value
  1202. * Output         : None
  1203. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1204. *******************************************************************************/
  1205. status_t LIS3DSH_ACC_GetSatusReg(void *handle, u8_t* val) {

  1206.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_STATUS, val, 1) )
  1207.       return MEMS_ERROR;
  1208.   
  1209.   return MEMS_SUCCESS;  
  1210. }

  1211.       
  1212. /*******************************************************************************
  1213. * Function Name  : GetSatusBIT
  1214. * Description    : Read the status register BIT
  1215. * Input          : STATUS_REG_ZYXOR, STATUS_REG_ZOR, STATUS_REG_YOR, STATUS_REG_XOR,
  1216.                    STATUS_REG_ZYXDA, STATUS_REG_ZDA, STATUS_REG_YDA, STATUS_REG_XDA, DATAREADY_BIT
  1217. * Output         : status register BIT
  1218. * Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
  1219. *******************************************************************************/
  1220. status_t LIS3DSH_ACC_GetSatusBit(void *handle, u8_t statusBIT) {
  1221.   u8_t value;  
  1222.   
  1223.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_STATUS, &value, 1) )
  1224.       return MEMS_ERROR;

  1225.   switch (statusBIT){
  1226.     case LIS3DSH_ACC_STATUS_REG_ZYXOR:     if(value & LIS3DSH_ACC_STATUS_REG_ZYXOR) return MEMS_SUCCESS;
  1227.                                else  return MEMS_ERROR;
  1228.     case LIS3DSH_ACC_STATUS_REG_ZOR:       if(value & LIS3DSH_ACC_STATUS_REG_ZOR) return MEMS_SUCCESS;
  1229.                                else  return MEMS_ERROR;
  1230.     case LIS3DSH_ACC_STATUS_REG_YOR:       if(value & LIS3DSH_ACC_STATUS_REG_YOR) return MEMS_SUCCESS;
  1231.                                else  return MEMS_ERROR;                              
  1232.     case LIS3DSH_ACC_STATUS_REG_XOR:       if(value & LIS3DSH_ACC_STATUS_REG_XOR) return MEMS_SUCCESS;
  1233.                                else  return MEMS_ERROR;   
  1234.     case LIS3DSH_ACC_STATUS_REG_ZYXDA:     if(value & LIS3DSH_ACC_STATUS_REG_ZYXDA) return MEMS_SUCCESS;
  1235.                                else  return MEMS_ERROR;
  1236.     case LIS3DSH_ACC_STATUS_REG_ZDA:       if(value & LIS3DSH_ACC_STATUS_REG_ZDA) return MEMS_SUCCESS;
  1237.                                else  return MEMS_ERROR;
  1238.     case LIS3DSH_ACC_STATUS_REG_YDA:       if(value & LIS3DSH_ACC_STATUS_REG_YDA) return MEMS_SUCCESS;
  1239.                                else  return MEMS_ERROR;
  1240.     case LIS3DSH_ACC_STATUS_REG_XDA:       if(value & LIS3DSH_ACC_STATUS_REG_XDA) return MEMS_SUCCESS;
  1241.                                else  return MEMS_ERROR;                                
  1242.    
  1243.   }
  1244. return MEMS_ERROR;
  1245. }

  1246.    
  1247. /*******************************************************************************
  1248. * Function Name  : GetAccAxesRaw
  1249. * Description    : Read the Acceleration Values Output Registers
  1250. * Input          : buffer to empty by AccAxesRaw_t Typedef
  1251. * Output         : None
  1252. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1253. *******************************************************************************/
  1254. status_t LIS3DSH_ACC_GetAccAxesRaw(void *handle, Type3Axis16bit_U* buff) {
  1255.   u8_t valueL;
  1256.   u8_t valueH;
  1257.   
  1258.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_X_L, &valueL, 1) )
  1259.       return MEMS_ERROR;
  1260.   
  1261.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_X_H, &valueH, 1) )
  1262.       return MEMS_ERROR;
  1263.   
  1264.   buff->i16bit[0] = (i16_t)( (valueH << 8) | valueL )/16;
  1265.   
  1266.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_Y_L, &valueL, 1) )
  1267.       return MEMS_ERROR;
  1268.   
  1269.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_Y_H, &valueH, 1) )
  1270.       return MEMS_ERROR;
  1271.   
  1272.   buff->i16bit[1] = (i16_t)( (valueH << 8) | valueL )/16;
  1273.   
  1274.    if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_Z_L, &valueL, 1) )
  1275.       return MEMS_ERROR;
  1276.   
  1277.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_OUT_Z_H, &valueH, 1) )
  1278.       return MEMS_ERROR;
  1279.   
  1280.   buff->i16bit[2] = (i16_t)( (valueH << 8) | valueL )/16;
  1281.   
  1282.   return MEMS_SUCCESS;  
  1283. }


  1284. /*******************************************************************************
  1285. * Function Name  : GetStatBIT
  1286. * Description    : Read single BIT status of STAT register
  1287. * Input          : Stat BIT Mask Flag (F_LONG,F_SYNC1...)
  1288. * Output         : None
  1289. * Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
  1290. *******************************************************************************/
  1291. status_t LIS3DSH_ACC_GetStatBIT(void *handle, u8_t StatBITMask) {
  1292.   u8_t value;
  1293.   
  1294.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_STAT, &value, 1) )
  1295.     return MEMS_ERROR;

  1296.   if(value & StatBITMask)    return MEMS_SUCCESS;
  1297.     return MEMS_ERROR;
  1298. }  


  1299. /*******************************************************************************
  1300. * Function Name  : GetFifoSourceReg
  1301. * Description    : Read Fifo source Register
  1302. * Input          : Byte to empty by FIFO source register value
  1303. * Output         : None
  1304. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1305. *******************************************************************************/
  1306. status_t LIS3DSH_ACC_GetFifoSourceReg(void *handle, u8_t* val) {
  1307.   
  1308.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_FIFO_SRC, val, 1) )
  1309.     return MEMS_ERROR;
  1310.   
  1311.   return MEMS_SUCCESS;
  1312. }


  1313. /*******************************************************************************
  1314. * Function Name  : GetFifoSourceBit
  1315. * Description    : Read Fifo WaterMark source bit
  1316. * Input          : FIFO_WTM_S, FIFO_EMPTY_S, FIFO_EMPTY_S...
  1317. * Output         : None
  1318. * Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
  1319. *******************************************************************************/
  1320. status_t LIS3DSH_ACC_GetFifoSourceBit(void *handle, u8_t statusBIT){
  1321.   u8_t value;  
  1322.   
  1323.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_FIFO_SRC, &value, 1) )
  1324.       return MEMS_ERROR;

  1325.   if(statusBIT == LIS3DSH_ACC_FIFO_WTM_S){
  1326.     if(value & LIS3DSH_ACC_FIFO_WTM_S)     return MEMS_SUCCESS;
  1327.     else  return MEMS_ERROR;  
  1328.   }
  1329.   
  1330.   if(statusBIT == LIS3DSH_ACC_FIFO_OVRN_S){
  1331.     if(value & LIS3DSH_ACC_FIFO_OVRN_S)   return MEMS_SUCCESS;
  1332.     else  return MEMS_ERROR;  
  1333.   }

  1334.   if(statusBIT == LIS3DSH_ACC_FIFO_EMPTY_S){
  1335.     if(value & LIS3DSH_ACC_FIFO_EMPTY_S)   return MEMS_SUCCESS;
  1336.     else  return MEMS_ERROR;  
  1337.   }
  1338.   
  1339. return MEMS_ERROR;
  1340. }


  1341. /*******************************************************************************
  1342. * Function Name  : GetFifoSourceFSS
  1343. * Description    : Read Fifo source Data Stored
  1344. * Input          : Byte to empty by FIFO source Data Stored value
  1345. * Output         : None
  1346. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1347. *******************************************************************************/
  1348. status_t LIS3DSH_ACC_GetFifoSourceFSS(void *handle, u8_t* val) {
  1349.   
  1350.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_FIFO_SRC, val, 1) )
  1351.     return MEMS_ERROR;

  1352.   *val &= 0x1F;
  1353.   
  1354.   return MEMS_SUCCESS;
  1355. }     


  1356. /*******************************************************************************
  1357. * Function Name  : ReadFifoData
  1358. * Description    : Read all Fifo Data stored
  1359. * Input          : AccAxesRaw_t Buffer to empty by FIFO Data Stored value, Byte to empty by depth of FIFO
  1360. * Note                 : Must call this function every [nMax sample * ODR] seconds max (or more fastly)
  1361. * Output         : None
  1362. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1363. *******************************************************************************/
  1364. status_t LIS3DSH_ACC_ReadFifoData(void *handle, Type3Axis16bit_U* FifoBuff, u8_t* depth) {
  1365.   u8_t val=0;
  1366.   u8_t i=0;
  1367.   i8_t j=0;
  1368.   Type3Axis16bit_U data;
  1369.   
  1370.   
  1371.   if(! LIS3DSH_ACC_GetFifoSourceFSS(handle, &val))  //read FSS fifo value
  1372.   return MEMS_ERROR;

  1373.   if(val<1) return MEMS_ERROR; //there aren't fifo value

  1374.   //read n data from FIFO
  1375.   for(j=val;j>=0;j--){
  1376.         LIS3DSH_ACC_GetAccAxesRaw(handle, &data);
  1377.         FifoBuff[i].i16bit[0] = data.i16bit[0];
  1378.         FifoBuff[i].i16bit[1] = data.i16bit[1];
  1379.         FifoBuff[i].i16bit[2] = data.i16bit[2];
  1380.         i++;
  1381.         }
  1382.   
  1383.   *depth = val;
  1384.   
  1385.   return MEMS_SUCCESS;
  1386. }   


  1387. /*******************************************************************************
  1388. * Function Name  : SetSPIInterface
  1389. * Description    : Set SPI mode: 3 Wire Interface OR 4 Wire Interface
  1390. * Input          : SPI_3_WIRE, SPI_4_WIRE
  1391. * Output         : None
  1392. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1393. *******************************************************************************/
  1394. status_t LIS3DSH_ACC_SetSPIInterface(void *handle, LIS3DSH_ACC_SPIMode_t spi) {
  1395.   u8_t value;
  1396.   
  1397.   if( !LIS3DSH_ACC_ReadReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  1398.     return MEMS_ERROR;
  1399.                   
  1400.   value &= 0xFE;
  1401.   value |= spi<<LIS3DSH_ACC_SIM;
  1402.   
  1403.   if( !LIS3DSH_ACC_WriteReg(handle, LIS3DSH_ACC_CNTL5, &value, 1) )
  1404.     return MEMS_ERROR;
  1405.   
  1406.   return MEMS_SUCCESS;
  1407. }


  1408. /*******************************************************************************
  1409. * Function Name  : SetSMCodeReg
  1410. * Description    : Set single SMx Code Register byte
  1411. * Input          : Code Address, Code (Byte)
  1412. * Output         : None
  1413. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1414. *******************************************************************************/
  1415. status_t LIS3DSH_ACC_SetSMCodeReg(void *handle, u8_t CodeADD, u8_t CodeByte) {

  1416.   //check correct address
  1417.   if(! (((CodeADD >= 0x40)&&(CodeADD <= 0x4F)) || ((CodeADD >= 0x60)&&(CodeADD <= 0x6F))) )
  1418.         return MEMS_ERROR;
  1419.   
  1420.     if( !LIS3DSH_ACC_WriteReg(handle, CodeADD, &CodeByte, 1) )
  1421.     return MEMS_ERROR;
  1422.   
  1423.   return MEMS_SUCCESS;
  1424. }


  1425. /*******************************************************************************
  1426. * Function Name  : SetSMBufferCodeReg
  1427. * Description    : Set All SMx Code Registers by Buffer input
  1428. * Input          : SMx, Code Buffer[16]
  1429. * Output         : None
  1430. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1431. *******************************************************************************/
  1432. status_t LIS3DSH_ACC_SetSMBufferCodeReg(void *handle, LIS3DSH_ACC_SM_t sm, u8_t* CodeBuff) {
  1433.   u8_t reg=0;
  1434.   u8_t i=0;
  1435.   
  1436.   switch(sm){
  1437.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_ST1_1; break;
  1438.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_ST1_2; break;
  1439.   }  
  1440.    
  1441.   for(i=0;i<16;i++){
  1442.     if( !LIS3DSH_ACC_WriteReg(handle, reg+i, &CodeBuff[i], 1) )
  1443.     return MEMS_ERROR;
  1444.   }
  1445.   
  1446.   return MEMS_SUCCESS;
  1447. }


  1448. /*******************************************************************************
  1449. * Function Name  : GetSMCodeRegister
  1450. * Description    : Get single code register number of SMx
  1451. * Input          : SMx, Register Number [1,16], variable to empty
  1452. * Output         : None
  1453. * Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
  1454. *******************************************************************************/
  1455. status_t LIS3DSH_ACC_GetSMCodeRegister(void *handle, LIS3DSH_ACC_SM_t sm, u8_t RegNumber, u8_t* val) {
  1456.   u8_t reg=0;

  1457.   if((RegNumber==0)||(RegNumber>16))    return MEMS_ERROR;
  1458.   
  1459.   switch(sm){
  1460.   case LIS3DSH_ACC_SM1:  reg = LIS3DSH_ACC_ST1_1; break;
  1461.   case LIS3DSH_ACC_SM2:  reg = LIS3DSH_ACC_ST1_2; break;
  1462.   }  
  1463.    
  1464.     if( !LIS3DSH_ACC_ReadReg(handle, reg + RegNumber-1, val, 1) )
  1465.     return MEMS_ERROR;
  1466.   
  1467.   return MEMS_SUCCESS;
  1468. }
复制代码

虾扯蛋


回复

使用道具 举报

410

TA的帖子

0

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2017-7-7 13:59 | 显示全部楼层


回复

使用道具 举报

3052

TA的帖子

0

TA的资源

五彩晶圆(初级)

Rank: 7Rank: 7Rank: 7

发表于 2017-7-8 09:58 | 显示全部楼层
多谢来分享啊                  
                                 


回复

使用道具 举报

771

TA的帖子

2

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2017-7-8 10:45 | 显示全部楼层
牛 多谢分享~
物致DIY 欢迎你的加入~
QQ群:646461928 公众号:智物知心致成
小店


回复

使用道具 举报

7

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-7-21 11:37 | 显示全部楼层


回复

使用道具 举报

4

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-7-26 10:04 | 显示全部楼层
太牛了,多谢分享!


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-8-8 11:07 | 显示全部楼层
LIS3DSH的有限状态机实现运动识别功能怎么配置,大家有demo吗?谢谢

点评

这个驱动包里有状态机的配置函数状态机的具体使用网上的资料不多 你可以多看看数据手册 或者参考一下这个驱动 [mw_shl_code=c,true]/******************** (C) COPYRIGHT 2012 STMicroelectronics ************  详情 回复 发表于 2017-8-9 11:21
nmg
去论坛直接发帖,看到的网友更多。回复帖关注度很少的  详情 回复 发表于 2017-8-8 11:43


回复

使用道具 举报

3508

TA的帖子

180

TA的资源

管理员

Rank: 13Rank: 13Rank: 13Rank: 13

发表于 2017-8-8 11:43 | 显示全部楼层
恒丶佣兵 发表于 2017-8-8 11:07
LIS3DSH的有限状态机实现运动识别功能怎么配置,大家有demo吗?谢谢

去论坛直接发帖,看到的网友更多。回复帖关注度很少的


回复

使用道具 举报

4

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-8-8 23:45 | 显示全部楼层
看起来很不错的样子


回复

使用道具 举报

5701

TA的帖子

9

TA的资源

版主

Rank: 6Rank: 6

发表于 2017-8-9 11:21 | 显示全部楼层
恒丶佣兵 发表于 2017-8-8 11:07
LIS3DSH的有限状态机实现运动识别功能怎么配置,大家有demo吗?谢谢

这个驱动包里有状态机的配置函数状态机的具体使用网上的资料不多
你可以多看看数据手册
或者参考一下这个驱动

  1. /******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
  2. *
  3. * File Name                : lis3dsh_acc.c
  4. * Authors                : MSH - Motion Mems BU - Application Team
  5. *                        : Matteo Dameno ([email]matteo.dameno@st.com[/email])
  6. *                        : Denis Ciocca ([email]denis.ciocca@st.com[/email])
  7. *                        : Author is willing to be considered the contact
  8. *                        : and update point for the driver.
  9. * Version                : V.1.2.2
  10. * Date                        : 2012/Dec/15
  11. * Description                : LIS3DSH accelerometer driver
  12. *
  13. *******************************************************************************
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License version 2 as
  17. * published by the Free Software Foundation.
  18. *
  19. * THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
  20. * OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE
  21. * PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT.
  22. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  23. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  24. * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  25. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  26. *
  27. * THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
  28. *
  29. ******************************************************************************
  30. Version History.
  31.         V 1.0.0                First Release
  32.         V 1.0.2                I2C address bugfix
  33.         V 1.2.0                Registers names compliant to correct datasheet
  34.         V.1.2.1                Removed enable_interrupt_output sysfs file, manage int1
  35.                         and int2, implements int1 isr.
  36.         V.1.2.2                Modified state program loadiing defines, removed
  37.                         state machine program.
  38. ******************************************************************************/

  39. #include        <linux/init.h>
  40. #include        <linux/module.h>
  41. #include        <linux/err.h>
  42. #include        <linux/errno.h>
  43. #include        <linux/delay.h>
  44. #include        <linux/fs.h>
  45. #include        <linux/i2c.h>
  46. #include        <linux/input.h>
  47. #include        <linux/uaccess.h>
  48. #include        <linux/workqueue.h>
  49. #include        <linux/irq.h>
  50. #include        <linux/gpio.h>
  51. #include        <linux/interrupt.h>
  52. #include        <linux/slab.h>

  53. /* #include        "lis3dsh.h" */
  54. #include        <linux/input/lis3dsh.h>

  55. //#define DEBUG

  56. /* set to 1 to enable SM program and parameters loading */
  57. /* set to 0 to leave unused */
  58. #define LOAD_SM1_PROGRAM        1
  59. #define LOAD_SP1_PARAMETERS        1
  60. #define LOAD_SM2_PROGRAM        1
  61. #define LOAD_SP2_PARAMETERS        1

  62. #define G_MAX                        23920640        /* ug */
  63. #define I2C_RETRY_DELAY                5                /* Waiting for signals [ms] */
  64. #define I2C_RETRIES                5                /* Number of retries */
  65. #define I2C_AUTO_INCREMENT        0x00                /* Autoincrement i2c address */

  66. #define SENSITIVITY_2G                60                /* ug/LSB        */
  67. #define SENSITIVITY_4G                120                /* ug/LSB        */
  68. #define SENSITIVITY_6G                180                /* ug/LSB        */
  69. #define SENSITIVITY_8G                240                /* ug/LSB        */
  70. #define SENSITIVITY_16G                730                /* ug/LSB        */

  71. #define LIS3DSH_FS_MASK        (0x38)

  72. /* Output Data Rates ODR */
  73. #define LIS3DSH_ODR_MASK        (0XF0)
  74. #define LIS3DSH_PM_OFF                (0x00)                /* OFF */
  75. #define LIS3DSH_ODR3_125        (0x10)                /*    3.125 Hz */
  76. #define LIS3DSH_ODR6_25                (0x20)                /*    6.25  Hz */
  77. #define LIS3DSH_ODR12_5                (0x30)                /*   12.5   Hz */
  78. #define LIS3DSH_ODR25                (0x40)                /*   25     Hz */
  79. #define LIS3DSH_ODR50                (0x50)                /*   50     Hz */
  80. #define LIS3DSH_ODR100                (0x60)                /*  100     Hz */
  81. #define LIS3DSH_ODR400                (0x70)                /*  400     Hz */
  82. #define LIS3DSH_ODR800                (0x80)                /*  800     Hz */
  83. #define LIS3DSH_ODR1600                (0x90)                /* 1600     Hz */

  84. /* Registers configuration Mask and settings */
  85. /* ----CTRLREGx */
  86. #define LIS3DSH_INTEN_MASK                (0x01)
  87. #define LIS3DSH_INTEN_OFF                (0x00)
  88. #define LIS3DSH_INTEN_ON                (0x01)

  89. /* CTRLREG1 */
  90. #define LIS3DSH_HIST1_MASK                (0xE0)
  91. #define LIS3DSH_SM1INT_PIN_MASK                (0x08)
  92. #define LIS3DSH_SM1INT_PININT2                (0x08)
  93. #define LIS3DSH_SM1INT_PININT1                (0x00)
  94. #define LIS3DSH_SM1_EN_MASK                (0x01)
  95. #define LIS3DSH_SM1_EN_ON                (0x01)
  96. #define LIS3DSH_SM1_EN_OFF                (0x00)
  97. /* */

  98. /* CTRLREG2 */
  99. #define LIS3DSH_HIST2_MASK                (0xE0)
  100. #define LIS3DSH_SM2INT_PIN_MASK                (0x08)
  101. #define LIS3DSH_SM2INT_PININT2                (0x08)
  102. #define LIS3DSH_SM2INT_PININT1                (0x00)
  103. #define LIS3DSH_SM2_EN_MASK                (0x01)
  104. #define LIS3DSH_SM2_EN_ON                (0x01)
  105. #define LIS3DSH_SM2_EN_OFF                (0x00)
  106. /* */

  107. /* CTRLREG3 */
  108. #define LIS3DSH_INT_ACT_MASK                (0x01 << 6)
  109. #define LIS3DSH_INT_ACT_H                (0x01 << 6)
  110. #define LIS3DSH_INT_ACT_L                (0x00)

  111. #define LIS3DSH_INT2_EN_MASK                (0x01 << 4)
  112. #define LIS3DSH_INT2_EN_ON                (0x01 << 4)
  113. #define LIS3DSH_INT2_EN_OFF                (0x00)

  114. #define LIS3DSH_INT1_EN_MASK                (0x01 << 3)
  115. #define LIS3DSH_INT1_EN_ON                (0x01 << 3)
  116. #define LIS3DSH_INT1_EN_OFF                (0x00)
  117. /* */

  118. /* CTRLREG4 */
  119. #define LIS3DSH_BDU_EN                        (0x08)
  120. #define LIS3DSH_ALL_AXES                (0x07)
  121. /* */

  122. /* STATUS REG BITS */
  123. #define LIS3DSH_STAT_INTSM1_BIT                (0x01 << 3)
  124. #define LIS3DSH_STAT_INTSM2_BIT                (0x01 << 2)

  125. #define OUT_AXISDATA_REG                LIS3DSH_OUTX_L
  126. #define WHOAMI_LIS3DSH_ACC                (0x3F)        /* Expected content for WAI */

  127. /*        CONTROL REGISTERS        */
  128. #define LIS3DSH_WHO_AM_I                (0x0F)        /* WhoAmI register Address */

  129. #define LIS3DSH_OUTX_L                        (0x28)        /* Output X LSByte */
  130. #define LIS3DSH_OUTX_H                        (0x29)        /* Output X MSByte */
  131. #define LIS3DSH_OUTY_L                        (0x2A)        /* Output Y LSByte */
  132. #define LIS3DSH_OUTY_H                        (0x2B)        /* Output Y MSByte */
  133. #define LIS3DSH_OUTZ_L                        (0x2C)        /* Output Z LSByte */
  134. #define LIS3DSH_OUTZ_H                        (0x2D)        /* Output Z MSByte */
  135. #define LIS3DSH_LC_L                        (0x16)        /* LSByte Long Counter Status */
  136. #define LIS3DSH_LC_H                        (0x17)        /* MSByte Long Counter Status */

  137. #define LIS3DSH_INTERR_STAT                (0x18)        /* Interrupt Status */

  138. #define LIS3DSH_STATUS_REG                (0x27)        /* Status */

  139. #define LIS3DSH_CTRL_REG1                (0x21)        /* control reg 1 */
  140. #define LIS3DSH_CTRL_REG2                (0x22)        /* control reg 2 */
  141. #define LIS3DSH_CTRL_REG3                (0x23)        /* control reg 3 */
  142. #define LIS3DSH_CTRL_REG4                (0x20)        /* control reg 4 */
  143. #define LIS3DSH_CTRL_REG5                (0x24)        /* control reg 5 */
  144. #define LIS3DSH_CTRL_REG6                (0x25)        /* control reg 6 */

  145. #define LIS3DSH_OFF_X                        (0x10)        /* Offset X Corr */
  146. #define LIS3DSH_OFF_Y                        (0x11)        /* Offset Y Corr */
  147. #define LIS3DSH_OFF_Z                        (0x12)        /* Offset Z Corr */

  148. #define LIS3DSH_CS_X                        (0x13)        /* Const Shift X */
  149. #define LIS3DSH_CS_Y                        (0x14)        /* Const Shift Y */
  150. #define LIS3DSH_CS_Z                        (0x15)        /* Const Shift Z */

  151. #define LIS3DSH_VFC_1                        (0x1B)        /* Vect Filter Coeff 1 */
  152. #define LIS3DSH_VFC_2                        (0x1C)        /* Vect Filter Coeff 2 */
  153. #define LIS3DSH_VFC_3                        (0x1D)        /* Vect Filter Coeff 3 */
  154. #define LIS3DSH_VFC_4                        (0x1E)        /* Vect Filter Coeff 4 */


  155.         /* state program 1 */
  156. #define LIS3DSH_STATEPR1        (0X40)        /*        State Program 1 16 bytes */

  157. #define LIS3DSH_TIM4_1                (0X50)        /*        SPr1 Timer4                */
  158. #define LIS3DSH_TIM3_1                (0X51)        /*        SPr1 Timer3                */
  159. #define LIS3DSH_TIM2_1                (0X52)        /*        SPr1 Timer2        2bytes        */
  160. #define LIS3DSH_TIM1_1                (0X54)        /*        SPr1 Timer1        2bytes        */

  161. #define LIS3DSH_THRS2_1                (0X56)        /*        SPr1 Threshold1                */
  162. #define LIS3DSH_THRS1_1                (0X57)        /*        SPr1 Threshold2                */
  163. #define LIS3DSH_SA_1                (0X59)        /*        SPr1 Swap Axis Sign Msk        */
  164. #define LIS3DSH_MA_1                (0X5A)        /*        SPr1 Axis Sign Msk        */
  165. #define LIS3DSH_SETT_1                (0X5B)        /*        SPr1                         */
  166. #define LIS3DSH_PPRP_1                (0X5C)        /*        SPr1 ProgPointer ResetPointer */
  167. #define LIS3DSH_TC_1                (0X5D)        /*        SPr1                 2bytes        */
  168. #define LIS3DSH_OUTS_1                (0X5F)        /*        SPr1                         */

  169.         /* state program 2 */
  170. #define LIS3DSH_STATEPR2        (0X60)        /*        State Program 2 16 bytes */

  171. #define LIS3DSH_TIM4_2                (0X70)        /*        SPr2 Timer4                */
  172. #define LIS3DSH_TIM3_2                (0X71)        /*        SPr2 Timer3                */
  173. #define LIS3DSH_TIM2_2                (0X72)        /*        SPr2 Timer2        2bytes        */
  174. #define LIS3DSH_TIM1_2                (0X74)        /*        SPr2 Timer1        2bytes        */

  175. #define LIS3DSH_THRS2_2                (0X76)        /*        SPr2 Threshold1                */
  176. #define LIS3DSH_THRS1_2                (0X77)        /*        SPr2 Threshold2                */
  177. #define LIS3DSH_DES_2                (0X78)        /*        SPr2 Decimation                */
  178. #define LIS3DSH_SA_2                (0X79)        /*        SPr2 Swap Axis Sign Msk        */
  179. #define LIS3DSH_MA_2                (0X7A)        /*        SPr2 Axis Sign Msk        */
  180. #define LIS3DSH_SETT_2                (0X7B)        /*        SPr2                         */
  181. #define LIS3DSH_PPRP_2                (0X7C)        /*        SPr2 ProgPointer ResetPointer */
  182. #define LIS3DSH_TC_2                (0X7D)        /*        SPr2                 2bytes        */
  183. #define LIS3DSH_OUTS_2                (0X7F)        /*        SPr2                         */
  184. /*        end CONTROL REGISTRES        */


  185. /* RESUME STATE INDICES */
  186. #define RES_LIS3DSH_LC_L                        0
  187. #define RES_LIS3DSH_LC_H                        1

  188. #define RES_LIS3DSH_CTRL_REG4                        2
  189. #define RES_LIS3DSH_CTRL_REG1                        3
  190. #define RES_LIS3DSH_CTRL_REG2                        4
  191. #define RES_LIS3DSH_CTRL_REG3                        5
  192. #define RES_LIS3DSH_CTRL_REG5                        6
  193. #define RES_LIS3DSH_CTRL_REG6                        7

  194. #define RES_LIS3DSH_OFF_X                        8
  195. #define RES_LIS3DSH_OFF_Y                        9
  196. #define RES_LIS3DSH_OFF_Z                        10

  197. #define RES_LIS3DSH_CS_X                        11
  198. #define RES_LIS3DSH_CS_Y                        12
  199. #define RES_LIS3DSH_CS_Z                        13

  200. #define RES_LIS3DSH_VFC_1                        14
  201. #define RES_LIS3DSH_VFC_2                        15
  202. #define RES_LIS3DSH_VFC_3                        16
  203. #define RES_LIS3DSH_VFC_4                        17

  204. #define RES_LIS3DSH_THRS3                        18

  205. #define RES_LIS3DSH_TIM4_1                        20
  206. #define RES_LIS3DSH_TIM3_1                        21
  207. #define RES_LIS3DSH_TIM2_1_L                        22
  208. #define RES_LIS3DSH_TIM2_1_H                        23
  209. #define RES_LIS3DSH_TIM1_1_L                        24
  210. #define RES_LIS3DSH_TIM1_1_H                        25

  211. #define RES_LIS3DSH_THRS2_1                        26
  212. #define RES_LIS3DSH_THRS1_1                        27
  213. #define RES_LIS3DSH_SA_1                        28
  214. #define RES_LIS3DSH_MA_1                        29
  215. #define RES_LIS3DSH_SETT_1                        30

  216. #define RES_LIS3DSH_TIM4_2                        31
  217. #define RES_LIS3DSH_TIM3_2                        32
  218. #define RES_LIS3DSH_TIM2_2_L                        33
  219. #define RES_LIS3DSH_TIM2_2_H                        34
  220. #define RES_LIS3DSH_TIM1_2_L                        35
  221. #define RES_LIS3DSH_TIM1_2_H                        36

  222. #define RES_LIS3DSH_THRS2_2                        37
  223. #define RES_LIS3DSH_THRS1_2                        38
  224. #define RES_LIS3DSH_DES_2                        39
  225. #define RES_LIS3DSH_SA_2                        40
  226. #define RES_LIS3DSH_MA_2                        41
  227. #define RES_LIS3DSH_SETT_2                        42

  228. #define LIS3DSH_RESUME_ENTRIES                        43



  229. #define LIS3DSH_STATE_PR_SIZE                        16
  230. /* end RESUME STATE INDICES */

  231. /* STATE PROGRAMS ENABLE CONTROLS */
  232. #define LIS3DSH_SM1_DIS_SM2_DIS                        (0x00)
  233. #define LIS3DSH_SM1_EN_SM2_DIS                        (0x01)
  234. #define LIS3DSH_SM1_DIS_SM2_EN                        (0x02)
  235. #define LIS3DSH_SM1_EN_SM2_EN                        (0x03)

  236. /* INTERRUPTS ENABLE CONTROLS */
  237. #define LIS3DSH_INT1_DIS_INT2_DIS                (0x00)
  238. #define LIS3DSH_INT1_EN_INT2_DIS                (0x01)
  239. #define LIS3DSH_INT1_DIS_INT2_EN                (0x02)
  240. #define LIS3DSH_INT1_EN_INT2_EN                        (0x03)

  241. struct {
  242.         unsigned int cutoff_ms;
  243.         unsigned int mask;
  244. } lis3dsh_acc_odr_table[] = {
  245.                 {    1, LIS3DSH_ODR1600 },
  246.                 {    3, LIS3DSH_ODR400  },
  247.                 {   10, LIS3DSH_ODR100  },
  248.                 {   20, LIS3DSH_ODR50   },
  249.                 {   40, LIS3DSH_ODR25   },
  250.                 {   80, LIS3DSH_ODR12_5 },
  251.                 {  160, LIS3DSH_ODR6_25 },
  252.                 {  320, LIS3DSH_ODR3_125},
  253. };

  254. static struct lis3dsh_acc_platform_data default_lis3dsh_acc_pdata = {
  255.         .fs_range = LIS3DSH_ACC_G_2G,
  256.         .axis_map_x = 0,
  257.         .axis_map_y = 1,
  258.         .axis_map_z = 2,
  259.         .negate_x = 0,
  260.         .negate_y = 0,
  261.         .negate_z = 0,
  262.         .poll_interval = 10,
  263.         .min_interval = LIS3DSH_ACC_MIN_POLL_PERIOD_MS,
  264.         .gpio_int1 = LIS3DSH_ACC_DEFAULT_INT1_GPIO,
  265.         .gpio_int2 = LIS3DSH_ACC_DEFAULT_INT2_GPIO,
  266. };

  267. static int int1_gpio = LIS3DSH_ACC_DEFAULT_INT1_GPIO;
  268. static int int2_gpio = LIS3DSH_ACC_DEFAULT_INT2_GPIO;
  269. module_param(int1_gpio, int, S_IRUGO);
  270. module_param(int2_gpio, int, S_IRUGO);
  271. MODULE_PARM_DESC(int1_gpio, "integer: gpio number being assined to interrupt PIN1");
  272. MODULE_PARM_DESC(int2_gpio, "integer: gpio number being assined to interrupt PIN2");

  273. struct lis3dsh_acc_data {
  274.         struct i2c_client *client;
  275.         struct lis3dsh_acc_platform_data *pdata;

  276.         struct mutex lock;
  277.         struct delayed_work input_work;

  278.         struct input_dev *input_dev;

  279.         int hw_initialized;
  280.         /* hw_working=-1 means not tested yet */
  281.         int hw_working;
  282.         atomic_t enabled;
  283.         int on_before_suspend;
  284.         int use_smbus;

  285.         u16 sensitivity;
  286.         u8 stateprogs_enable_setting;

  287.         u8 resume_state[LIS3DSH_RESUME_ENTRIES];
  288.         u8 resume_stmach_program1[LIS3DSH_STATE_PR_SIZE];
  289.         u8 resume_stmach_program2[LIS3DSH_STATE_PR_SIZE];

  290.         int irq1;
  291.         struct work_struct irq1_work;
  292.         struct workqueue_struct *irq1_work_queue;
  293.         int irq2;
  294.         struct work_struct irq2_work;
  295.         struct workqueue_struct *irq2_work_queue;

  296. #ifdef DEBUG
  297.         u8 reg_addr;
  298. #endif
  299. };


  300. /* sets default init values to be written in registers at probe stage */
  301. static void lis3dsh_acc_set_init_register_values(struct lis3dsh_acc_data *acc)
  302. {
  303.         acc->resume_state[RES_LIS3DSH_LC_L] = 0x00;
  304.         acc->resume_state[RES_LIS3DSH_LC_H] = 0x00;

  305.         acc->resume_state[RES_LIS3DSH_CTRL_REG1] = (0x00 | LIS3DSH_SM1INT_PININT1);
  306.         acc->resume_state[RES_LIS3DSH_CTRL_REG2] = (0x00 | LIS3DSH_SM2INT_PININT1);
  307.         acc->resume_state[RES_LIS3DSH_CTRL_REG3] = LIS3DSH_INT_ACT_H;
  308.         if(acc->pdata->gpio_int1 >= 0)
  309.                 acc->resume_state[RES_LIS3DSH_CTRL_REG3] =
  310.                                 acc->resume_state[RES_LIS3DSH_CTRL_REG3] | \
  311.                                         LIS3DSH_INT1_EN_ON;
  312.         if(acc->pdata->gpio_int2 >= 0)
  313.                 acc->resume_state[RES_LIS3DSH_CTRL_REG3] =
  314.                                 acc->resume_state[RES_LIS3DSH_CTRL_REG3] | \
  315.                                         LIS3DSH_INT2_EN_ON;

  316.         acc->resume_state[RES_LIS3DSH_CTRL_REG4] = (LIS3DSH_BDU_EN |
  317.                                                         LIS3DSH_ALL_AXES);
  318.         acc->resume_state[RES_LIS3DSH_CTRL_REG5] = 0x00;
  319.         acc->resume_state[RES_LIS3DSH_CTRL_REG6] = 0x10;

  320.         acc->resume_state[RES_LIS3DSH_THRS3] = 0x00;
  321.         acc->resume_state[RES_LIS3DSH_OFF_X] = 0x00;
  322.         acc->resume_state[RES_LIS3DSH_OFF_Y] = 0x00;
  323.         acc->resume_state[RES_LIS3DSH_OFF_Z] = 0x00;

  324.         acc->resume_state[RES_LIS3DSH_CS_X] = 0x00;
  325.         acc->resume_state[RES_LIS3DSH_CS_Y] = 0x00;
  326.         acc->resume_state[RES_LIS3DSH_CS_Z] = 0x00;

  327.         acc->resume_state[RES_LIS3DSH_VFC_1] = 0x00;
  328.         acc->resume_state[RES_LIS3DSH_VFC_2] = 0x00;
  329.         acc->resume_state[RES_LIS3DSH_VFC_3] = 0x00;
  330.         acc->resume_state[RES_LIS3DSH_VFC_4] = 0x00;
  331. }

  332. static void lis3dsh_acc_set_init_statepr1_inst(struct lis3dsh_acc_data *acc)
  333. {
  334. #if (LOAD_SM1_PROGRAM == 1)
  335.         /* Place here state machine 1 program */
  336.         acc->resume_stmach_program1[0] = 0x00;
  337.         acc->resume_stmach_program1[1] = 0x00;
  338.         acc->resume_stmach_program1[2] = 0X00;
  339.         acc->resume_stmach_program1[3] = 0X00;
  340.         acc->resume_stmach_program1[4] = 0x00;
  341.         acc->resume_stmach_program1[5] = 0x00;
  342.         acc->resume_stmach_program1[6] = 0x00;
  343.         acc->resume_stmach_program1[7] = 0x00;
  344.         acc->resume_stmach_program1[8] = 0x00;
  345.         acc->resume_stmach_program1[9] = 0x00;
  346.         acc->resume_stmach_program1[10] = 0x00;
  347.         acc->resume_stmach_program1[11] = 0x00;
  348.         acc->resume_stmach_program1[12] = 0x00;
  349.         acc->resume_stmach_program1[13] = 0x00;
  350.         acc->resume_stmach_program1[14] = 0x00;
  351.         acc->resume_stmach_program1[15] = 0x00;
  352. #else
  353.         acc->resume_stmach_program1[0] = 0x00;
  354.         acc->resume_stmach_program1[1] = 0x00;
  355.         acc->resume_stmach_program1[2] = 0X00;
  356.         acc->resume_stmach_program1[3] = 0X00;
  357.         acc->resume_stmach_program1[4] = 0x00;
  358.         acc->resume_stmach_program1[5] = 0x00;
  359.         acc->resume_stmach_program1[6] = 0x00;
  360.         acc->resume_stmach_program1[7] = 0x00;
  361.         acc->resume_stmach_program1[8] = 0x00;
  362.         acc->resume_stmach_program1[9] = 0x00;
  363.         acc->resume_stmach_program1[10] = 0x00;
  364.         acc->resume_stmach_program1[11] = 0x00;
  365.         acc->resume_stmach_program1[12] = 0x00;
  366.         acc->resume_stmach_program1[13] = 0x00;
  367.         acc->resume_stmach_program1[14] = 0x00;
  368.         acc->resume_stmach_program1[15] = 0x00;
  369. #endif /* LOAD_SM1_PROGRAM */
  370. }

  371. static void lis3dsh_acc_set_init_statepr2_inst(struct lis3dsh_acc_data *acc)
  372. {
  373. #if (LOAD_SM2_PROGRAM == 1)
  374.         /* Place here state machine 2 program */
  375.         acc->resume_stmach_program2[0] = 0x00;
  376.         acc->resume_stmach_program2[1] = 0x00;
  377.         acc->resume_stmach_program2[2] = 0X00;
  378.         acc->resume_stmach_program2[3] = 0X00;
  379.         acc->resume_stmach_program2[4] = 0x00;
  380.         acc->resume_stmach_program2[5] = 0x00;
  381.         acc->resume_stmach_program2[6] = 0x00;
  382.         acc->resume_stmach_program2[7] = 0x00;
  383.         acc->resume_stmach_program2[8] = 0x00;
  384.         acc->resume_stmach_program2[9] = 0x00;
  385.         acc->resume_stmach_program2[10] = 0x00;
  386.         acc->resume_stmach_program2[11] = 0x00;
  387.         acc->resume_stmach_program2[12] = 0x00;
  388.         acc->resume_stmach_program2[13] = 0x00;
  389.         acc->resume_stmach_program2[14] = 0x00;
  390.         acc->resume_stmach_program2[15] = 0x00;
  391. #else
  392.         acc->resume_stmach_program2[0] = 0x00;
  393.         acc->resume_stmach_program2[1] = 0x00;
  394.         acc->resume_stmach_program2[2] = 0X00;
  395.         acc->resume_stmach_program2[3] = 0X00;
  396.         acc->resume_stmach_program2[4] = 0x00;
  397.         acc->resume_stmach_program2[5] = 0x00;
  398.         acc->resume_stmach_program2[6] = 0x00;
  399.         acc->resume_stmach_program2[7] = 0x00;
  400.         acc->resume_stmach_program2[8] = 0x00;
  401.         acc->resume_stmach_program2[9] = 0x00;
  402.         acc->resume_stmach_program2[10] = 0x00;
  403.         acc->resume_stmach_program2[11] = 0x00;
  404.         acc->resume_stmach_program2[12] = 0x00;
  405.         acc->resume_stmach_program2[13] = 0x00;
  406.         acc->resume_stmach_program2[14] = 0x00;
  407.         acc->resume_stmach_program2[15] = 0x00;
  408. #endif /* LOAD_SM2_PROGRAM */
  409. }

  410. static void lis3dsh_acc_set_init_statepr1_param(struct lis3dsh_acc_data *acc)
  411. {
  412. #if (LOAD_SP1_PARAMETERS == 1)
  413.         /* Place here state machine 1 parameters */
  414.         acc->resume_state[RES_LIS3DSH_TIM4_1] = 0x00;
  415.         acc->resume_state[RES_LIS3DSH_TIM3_1] = 0x00;
  416.         acc->resume_state[RES_LIS3DSH_TIM2_1_L] = 0x00;
  417.         acc->resume_state[RES_LIS3DSH_TIM2_1_H] = 0x00;
  418.         acc->resume_state[RES_LIS3DSH_TIM1_1_L] = 0x00;
  419.         acc->resume_state[RES_LIS3DSH_TIM1_1_H] = 0x00;
  420.         acc->resume_state[RES_LIS3DSH_THRS2_1] = 0x00;
  421.         acc->resume_state[RES_LIS3DSH_THRS1_1] = 0x00;
  422.         /* DES1 not available*/
  423.         acc->resume_state[RES_LIS3DSH_SA_1] = 0x00;
  424.         acc->resume_state[RES_LIS3DSH_MA_1] = 0x00;
  425.         acc->resume_state[RES_LIS3DSH_SETT_1] = 0x00;
  426. #else
  427.         acc->resume_state[RES_LIS3DSH_TIM4_1] = 0x00;
  428.         acc->resume_state[RES_LIS3DSH_TIM3_1] = 0x00;
  429.         acc->resume_state[RES_LIS3DSH_TIM2_1_L] = 0x00;
  430.         acc->resume_state[RES_LIS3DSH_TIM2_1_H] = 0x00;
  431.         acc->resume_state[RES_LIS3DSH_TIM1_1_L] = 0x00;
  432.         acc->resume_state[RES_LIS3DSH_TIM1_1_H] = 0x00;
  433.         acc->resume_state[RES_LIS3DSH_THRS2_1] = 0x00;
  434.         acc->resume_state[RES_LIS3DSH_THRS1_1] = 0x00;
  435.         /* DES1 not available*/
  436.         acc->resume_state[RES_LIS3DSH_SA_1] = 0x00;
  437.         acc->resume_state[RES_LIS3DSH_MA_1] = 0x00;
  438.         acc->resume_state[RES_LIS3DSH_SETT_1] = 0x00;
  439. #endif
  440. }

  441. static void lis3dsh_acc_set_init_statepr2_param(struct lis3dsh_acc_data *acc)
  442. {
  443. #if (LOAD_SP2_PARAMETERS == 1)
  444.         /* Place here state machine 2 parameters */
  445.         acc->resume_state[RES_LIS3DSH_TIM4_2] = 0x00;
  446.         acc->resume_state[RES_LIS3DSH_TIM3_2] = 0x00;
  447.         acc->resume_state[RES_LIS3DSH_TIM2_2_L] = 0x00;
  448.         acc->resume_state[RES_LIS3DSH_TIM2_2_H] = 0x00;
  449.         acc->resume_state[RES_LIS3DSH_TIM1_2_L] = 0x00;
  450.         acc->resume_state[RES_LIS3DSH_TIM1_2_H] = 0x00;
  451.         acc->resume_state[RES_LIS3DSH_THRS2_2] = 0x00;
  452.         acc->resume_state[RES_LIS3DSH_THRS1_2] = 0x00;
  453.         acc->resume_state[RES_LIS3DSH_DES_2] = 0x00;
  454.         acc->resume_state[RES_LIS3DSH_SA_2] = 0x00;
  455.         acc->resume_state[RES_LIS3DSH_MA_2] = 0x00;
  456.         acc->resume_state[RES_LIS3DSH_SETT_2] = 0x00;
  457. #else
  458.         acc->resume_state[RES_LIS3DSH_TIM4_2] = 0x00;
  459.         acc->resume_state[RES_LIS3DSH_TIM3_2] = 0x00;
  460.         acc->resume_state[RES_LIS3DSH_TIM2_2_L] = 0x00;
  461.         acc->resume_state[RES_LIS3DSH_TIM2_2_H] = 0x00;
  462.         acc->resume_state[RES_LIS3DSH_TIM1_2_L] = 0x00;
  463.         acc->resume_state[RES_LIS3DSH_TIM1_2_H] = 0x00;
  464.         acc->resume_state[RES_LIS3DSH_THRS2_2] = 0x00;
  465.         acc->resume_state[RES_LIS3DSH_THRS1_2] = 0x00;
  466.         acc->resume_state[RES_LIS3DSH_DES_2] = 0x00;
  467.         acc->resume_state[RES_LIS3DSH_SA_2] = 0x00;
  468.         acc->resume_state[RES_LIS3DSH_MA_2] = 0x00;
  469.         acc->resume_state[RES_LIS3DSH_SETT_2] = 0x00;
  470. #endif
  471. }

  472. static int lis3dsh_acc_i2c_read(struct lis3dsh_acc_data *acc,
  473.                                 u8 * buf, int len)
  474. {
  475.         int err;
  476.         int tries = 0;

  477.         struct i2c_msg        msgs[] = {
  478.                 {
  479.                         .addr = acc->client->addr,
  480.                         .flags = acc->client->flags & I2C_M_TEN,
  481.                         .len = 1,
  482.                         .buf = buf,
  483.                 },
  484.                 {
  485.                         .addr = acc->client->addr,
  486.                         .flags = (acc->client->flags & I2C_M_TEN) | I2C_M_RD,
  487.                         .len = len,
  488.                         .buf = buf,
  489.                 },
  490.         };

  491.         do {
  492.                 err = i2c_transfer(acc->client->adapter, msgs, 2);
  493.                 if (err != 2)
  494.                         msleep_interruptible(I2C_RETRY_DELAY);
  495.         } while ((err != 2) && (++tries < I2C_RETRIES));

  496.         if (err != 2) {
  497.                 dev_err(&acc->client->dev, "read transfer error\n");
  498.                 err = -EIO;
  499.         } else {
  500.                 err = 0;
  501.         }

  502.         return err;
  503. }

  504. static int lis3dsh_acc_i2c_write(struct lis3dsh_acc_data *acc, u8 * buf,
  505.                                                                 int len)
  506. {
  507.         int err;
  508.         int tries = 0;

  509.         struct i2c_msg msgs[] = {
  510.                 {
  511.                  .addr = acc->client->addr,
  512.                         .flags = acc->client->flags & I2C_M_TEN,
  513.                  .len = len + 1,
  514.                  .buf = buf,
  515.                  },
  516.         };

  517.         do {
  518.                 err = i2c_transfer(acc->client->adapter, msgs, 1);
  519.                 if (err != 1)
  520.                         msleep_interruptible(I2C_RETRY_DELAY);
  521.         } while ((err != 1) && (++tries < I2C_RETRIES));

  522.         if (err != 1) {
  523.                 dev_err(&acc->client->dev, "write transfer error\n");
  524.                 err = -EIO;
  525.         } else {
  526.                 err = 0;
  527.         }

  528.         return err;
  529. }

  530. static int lis3dsh_acc_i2c_update(struct lis3dsh_acc_data *acc,
  531.                                 u8 reg_address, u8 mask, u8 new_bit_values)
  532. {
  533.         int err = -1;
  534.         u8 rdbuf[1] = { reg_address };
  535.         u8 wrbuf[2] = { reg_address , 0x00 };

  536.         u8 init_val;
  537.         u8 updated_val;
  538.         err = lis3dsh_acc_i2c_read(acc, rdbuf, 1);
  539.         if (!(err < 0)) {
  540.                 init_val = rdbuf[0];
  541.                 updated_val = ((mask & new_bit_values) | ((~mask) & init_val));
  542.                 wrbuf[1] = updated_val;
  543.                 err = lis3dsh_acc_i2c_write(acc, wrbuf, 1);
  544.         }
  545.         return err;
  546. }

  547. static int lis3dsh_acc_hw_init(struct lis3dsh_acc_data *acc)
  548. {
  549.         int i;
  550.         int err = -1;
  551.         u8 buf[17];

  552.         pr_info("%s: hw init start\n", LIS3DSH_ACC_DEV_NAME);

  553.         buf[0] = LIS3DSH_WHO_AM_I;
  554.         err = lis3dsh_acc_i2c_read(acc, buf, 1);
  555.         if (err < 0) {
  556.         dev_warn(&acc->client->dev, "Error reading WHO_AM_I: is device "
  557.                 "available/working?\n");
  558.                 goto err_firstread;
  559.         } else
  560.                 acc->hw_working = 1;

  561.         if (buf[0] != WHOAMI_LIS3DSH_ACC) {
  562.         dev_err(&acc->client->dev,
  563.                 "device unknown. Expected: 0x%02x,"
  564.                 " Replies: 0x%02x\n", WHOAMI_LIS3DSH_ACC, buf[0]);
  565.                 err = -1; /* choose the right coded error */
  566.                 goto err_unknown_device;
  567.         }


  568.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_LC_L);
  569.         buf[1] = acc->resume_state[RES_LIS3DSH_LC_L];
  570.         buf[2] = acc->resume_state[RES_LIS3DSH_LC_H];
  571.         err = lis3dsh_acc_i2c_write(acc, buf, 2);
  572.         if (err < 0)
  573.                 goto err_resume_state;

  574.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_TIM4_1);
  575.         buf[1] = acc->resume_state[RES_LIS3DSH_TIM4_1];
  576.         buf[2] = acc->resume_state[RES_LIS3DSH_TIM3_1];
  577.         buf[3] = acc->resume_state[RES_LIS3DSH_TIM2_1_L];
  578.         buf[4] = acc->resume_state[RES_LIS3DSH_TIM2_1_H];
  579.         buf[5] = acc->resume_state[RES_LIS3DSH_TIM1_1_L];
  580.         buf[6] = acc->resume_state[RES_LIS3DSH_TIM1_1_H];
  581.         buf[7] = acc->resume_state[RES_LIS3DSH_THRS2_1];
  582.         buf[8] = acc->resume_state[RES_LIS3DSH_THRS1_1];
  583.         err = lis3dsh_acc_i2c_write(acc, buf, 8);
  584.         if (err < 0)
  585.                 goto err_resume_state;

  586.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_SA_1);
  587.         buf[1] = acc->resume_state[RES_LIS3DSH_SA_1];
  588.         buf[2] = acc->resume_state[RES_LIS3DSH_MA_1];
  589.         buf[3] = acc->resume_state[RES_LIS3DSH_SETT_1];
  590.         err = lis3dsh_acc_i2c_write(acc, buf, 3);
  591.         if (err < 0)
  592.                 goto err_resume_state;

  593.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_TIM4_2);
  594.         buf[1] = acc->resume_state[RES_LIS3DSH_TIM4_2];
  595.         buf[2] = acc->resume_state[RES_LIS3DSH_TIM3_2];
  596.         buf[3] = acc->resume_state[RES_LIS3DSH_TIM2_2_L];
  597.         buf[4] = acc->resume_state[RES_LIS3DSH_TIM2_2_H];
  598.         buf[5] = acc->resume_state[RES_LIS3DSH_TIM1_2_L];
  599.         buf[6] = acc->resume_state[RES_LIS3DSH_TIM1_2_H];
  600.         buf[7] = acc->resume_state[RES_LIS3DSH_THRS2_2];
  601.         buf[8] = acc->resume_state[RES_LIS3DSH_THRS1_2];
  602.         buf[9] = acc->resume_state[RES_LIS3DSH_DES_2];
  603.         buf[10] = acc->resume_state[RES_LIS3DSH_SA_2];
  604.         buf[11] = acc->resume_state[RES_LIS3DSH_MA_2];
  605.         buf[12] = acc->resume_state[RES_LIS3DSH_SETT_2];
  606.         err = lis3dsh_acc_i2c_write(acc, buf, 12);
  607.         if (err < 0)
  608.                 goto err_resume_state;

  609.         /*        state program 1 */
  610.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_STATEPR1);
  611.         for (i = 1; i <= LIS3DSH_STATE_PR_SIZE; i++) {
  612.                 buf[i] = acc->resume_stmach_program1[i-1];
  613.                 pr_debug("i=%d,sm pr1 buf[%d]=0x%02x\n", i, i, buf[i]);
  614.         };
  615.         err = lis3dsh_acc_i2c_write(acc, buf, LIS3DSH_STATE_PR_SIZE);
  616.         if (err < 0)
  617.                 goto err_resume_state;

  618.         /*        state program 2 */
  619.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_STATEPR2);
  620.         for(i = 1; i <= LIS3DSH_STATE_PR_SIZE; i++){
  621.                 buf[i] = acc->resume_stmach_program2[i-1];
  622.                 pr_debug("i=%d,sm pr2 buf[%d]=0x%02x\n", i, i, buf[i]);
  623.         };
  624.         err = lis3dsh_acc_i2c_write(acc, buf, LIS3DSH_STATE_PR_SIZE);
  625.         if (err < 0)
  626.                 goto err_resume_state;

  627.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_CTRL_REG5);
  628.         buf[1] = acc->resume_state[RES_LIS3DSH_CTRL_REG5];
  629.         buf[2] = acc->resume_state[RES_LIS3DSH_CTRL_REG6];
  630.         err = lis3dsh_acc_i2c_write(acc, buf, 2);
  631.         if (err < 0)
  632.                 goto err_resume_state;

  633.         buf[0] = (I2C_AUTO_INCREMENT | LIS3DSH_CTRL_REG1);
  634.         buf[1] = acc->resume_state[RES_LIS3DSH_CTRL_REG1];
  635.         buf[2] = acc->resume_state[RES_LIS3DSH_CTRL_REG2];
  636.         buf[3] = acc->resume_state[RES_LIS3DSH_CTRL_REG3];
  637.         err = lis3dsh_acc_i2c_write(acc, buf, 3);
  638.         if (err < 0)
  639.                 goto err_resume_state;

  640.         buf[0] = (LIS3DSH_CTRL_REG4);
  641.         buf[1] = acc->resume_state[RES_LIS3DSH_CTRL_REG4];
  642.         err = lis3dsh_acc_i2c_write(acc, buf, 1);
  643.         if (err < 0)
  644.                 goto err_resume_state;

  645.         acc->hw_initialized = 1;
  646.         pr_info("%s: hw init done\n", LIS3DSH_ACC_DEV_NAME);
  647.         return 0;

  648. err_firstread:
  649.         acc->hw_working = 0;
  650. err_unknown_device:
  651. err_resume_state:
  652.         acc->hw_initialized = 0;
  653.         dev_err(&acc->client->dev, "hw init error 0x%02x,0x%02x: %d\n", buf[0],
  654.                         buf[1], err);
  655.         return err;
  656. }

  657. static void lis3dsh_acc_device_power_off(struct lis3dsh_acc_data *acc)
  658. {
  659.         int err;

  660.         err = lis3dsh_acc_i2c_update(acc, LIS3DSH_CTRL_REG4,
  661.                                         LIS3DSH_ODR_MASK, LIS3DSH_PM_OFF);
  662.         if (err < 0)
  663.                 dev_err(&acc->client->dev, "soft power off failed: %d\n", err);

  664.         if (acc->pdata->power_off) {
  665.                 if(acc->pdata->gpio_int1)
  666.                         disable_irq_nosync(acc->irq1);
  667.                 if(acc->pdata->gpio_int2)
  668.                         disable_irq_nosync(acc->irq2);
  669.                 acc->pdata->power_off();
  670.                 acc->hw_initialized = 0;
  671.         }
  672.         if (acc->hw_initialized) {
  673.                 if(acc->pdata->gpio_int1 >= 0)
  674.                         disable_irq_nosync(acc->irq1);
  675.                 if(acc->pdata->gpio_int2 >= 0)
  676.                         disable_irq_nosync(acc->irq2);
  677.                 acc->hw_initialized = 0;
  678.         }
  679. }

  680. static int lis3dsh_acc_device_power_on(struct lis3dsh_acc_data *acc)
  681. {
  682.         int err = -1;

  683.         if (acc->pdata->power_on) {
  684.                 err = acc->pdata->power_on();
  685.                 if (err < 0) {
  686.                         dev_err(&acc->client->dev,
  687.                                         "power_on failed: %d\n", err);
  688.                         return err;
  689.                 }
  690.                 if(acc->pdata->gpio_int1 >= 0)
  691.                         enable_irq(acc->irq1);
  692.                 if(acc->pdata->gpio_int2 >= 0)
  693.                         enable_irq(acc->irq2);
  694.         }

  695.         if (!acc->hw_initialized) {
  696.                 err = lis3dsh_acc_hw_init(acc);
  697.                 if (acc->hw_working == 1 && err < 0) {
  698.                         lis3dsh_acc_device_power_off(acc);
  699.                         return err;
  700.                 }
  701.         }

  702.         if (acc->hw_initialized) {
  703.                 if(acc->pdata->gpio_int1 >= 0)
  704.                         enable_irq(acc->irq1);
  705.                 if(acc->pdata->gpio_int2 >= 0)
  706.                         enable_irq(acc->irq2);
  707.         }
  708.         return 0;
  709. }

  710. static irqreturn_t lis3dsh_acc_isr1(int irq, void *dev)
  711. {
  712.         struct lis3dsh_acc_data *acc = dev;

  713.         disable_irq_nosync(irq);
  714.         queue_work(acc->irq1_work_queue, &acc->irq1_work);
  715.         pr_debug("%s: isr1 queued\n", LIS3DSH_ACC_DEV_NAME);

  716.         return IRQ_HANDLED;
  717. }

  718. static irqreturn_t lis3dsh_acc_isr2(int irq, void *dev)
  719. {
  720.         struct lis3dsh_acc_data *acc = dev;

  721.         disable_irq_nosync(irq);
  722.         queue_work(acc->irq2_work_queue, &acc->irq2_work);
  723.         pr_debug("%s: isr2 queued\n", LIS3DSH_ACC_DEV_NAME);

  724.         return IRQ_HANDLED;
  725. }

  726. static void lis3dsh_acc_irq1_work_func(struct work_struct *work)
  727. {

  728.         int err = -1;
  729.         u8 rbuf[2], status;
  730.         struct lis3dsh_acc_data *acc;

  731.         acc = container_of(work, struct lis3dsh_acc_data, irq1_work);
  732.         /* TODO  add interrupt service procedure.
  733.                  ie:lis3dsh_acc_get_int_source(acc); */
  734.         pr_debug("%s: IRQ1 triggered\n", LIS3DSH_ACC_DEV_NAME);
  735.         /*  */
  736.         rbuf[0] = LIS3DSH_INTERR_STAT;
  737.         err = lis3dsh_acc_i2c_read(acc, rbuf, 1);
  738.         pr_debug("%s: INTERR_STAT_REG: 0x%02x\n",
  739.                                         LIS3DSH_ACC_DEV_NAME, rbuf[0]);
  740.         status = rbuf[0];
  741.         if(status & LIS3DSH_STAT_INTSM1_BIT) {
  742.                 rbuf[0] = LIS3DSH_OUTS_1;
  743.                 err = lis3dsh_acc_i2c_read(acc, rbuf, 1);
  744.                 pr_debug("%s: OUTS_1: 0x%02x\n",
  745.                                         LIS3DSH_ACC_DEV_NAME, rbuf[0]);
  746.         }
  747.         if(status & LIS3DSH_STAT_INTSM2_BIT) {
  748.                 rbuf[0] = LIS3DSH_OUTS_2;
  749.                 err = lis3dsh_acc_i2c_read(acc, rbuf, 1);
  750.                 pr_debug("%s: OUTS_2: 0x%02x\n",
  751.                                         LIS3DSH_ACC_DEV_NAME, rbuf[0]);
  752.         }
  753.         pr_debug("%s: IRQ1 served\n", LIS3DSH_ACC_DEV_NAME);
  754. exit:
  755.         enable_irq(acc->irq1);
  756.         pr_debug("%s: IRQ1 re-enabled\n", LIS3DSH_ACC_DEV_NAME);
  757. }

  758. static void lis3dsh_acc_irq2_work_func(struct work_struct *work)
  759. {
  760.         struct lis3dsh_acc_data *acc;

  761.         acc = container_of(work, struct lis3dsh_acc_data, irq2_work);
  762.         pr_debug("%s: IRQ2 triggered\n", LIS3DSH_ACC_DEV_NAME);
  763.         /* TODO  add interrupt service procedure.
  764.                  ie:lis3dsh_acc_get_stat_source(acc); */
  765.         /* ; */
  766.         pr_debug("%s: IRQ2 served\n", LIS3DSH_ACC_DEV_NAME);
  767. exit:
  768.         enable_irq(acc->irq2);
  769.         pr_debug("%s: IRQ2 re-enabled\n", LIS3DSH_ACC_DEV_NAME);
  770. }

  771. static int lis3dsh_acc_register_masked_update(struct lis3dsh_acc_data *acc,
  772.                 u8 reg_address, u8 mask, u8 new_bit_values, int resume_index)
  773. {
  774.         u8 config[2] = {0};
  775.         u8 init_val, updated_val;
  776.         int err;
  777.         int step = 0;

  778.         config[0] = reg_address;
  779.         err = lis3dsh_acc_i2c_read(acc, config, 1);
  780.         if (err < 0)
  781.                 goto error;
  782.         init_val = config[0];
  783.         acc->resume_state[resume_index] = init_val;
  784.         step = 1;
  785.         updated_val = ((mask & new_bit_values) | ((~mask) & init_val));
  786.         config[0] = reg_address;
  787.         config[1] = updated_val;
  788.         err = lis3dsh_acc_i2c_write(acc, config, 1);
  789.         if (err < 0)
  790.                 goto error;
  791.         acc->resume_state[resume_index] = updated_val;

  792.         return err;
  793.         error:
  794.                 dev_err(&acc->client->dev,
  795.                         "register 0x%02x update failed at step %d, error: %d\n",
  796.                                 config[0], step, err);
  797.         return err;
  798. }

  799. static int lis3dsh_acc_update_fs_range(struct lis3dsh_acc_data *acc,
  800.                                                                 u8 new_fs_range)
  801. {
  802.         int err=-1;
  803.         u16 sensitivity;

  804.         switch (new_fs_range) {
  805.         case LIS3DSH_ACC_G_2G:
  806.                 sensitivity = SENSITIVITY_2G;
  807.                 break;
  808.         case LIS3DSH_ACC_G_4G:
  809.                 sensitivity = SENSITIVITY_4G;
  810.                 break;
  811.         case LIS3DSH_ACC_G_6G:
  812.                 sensitivity = SENSITIVITY_6G;
  813.                 break;
  814.         case LIS3DSH_ACC_G_8G:
  815.                 sensitivity = SENSITIVITY_8G;
  816.                 break;
  817.         case LIS3DSH_ACC_G_16G:
  818.                 sensitivity = SENSITIVITY_16G;
  819.                 break;
  820.         default:
  821.                 dev_err(&acc->client->dev, "invalid g range requested: %u\n",
  822.                                 new_fs_range);
  823.                 return -EINVAL;
  824.         }

  825.         if (atomic_read(&acc->enabled)) {
  826.                 /* Updates configuration register 1,
  827.                 * which contains g range setting */
  828.                 err = lis3dsh_acc_register_masked_update(acc, LIS3DSH_CTRL_REG5,
  829.                 LIS3DSH_FS_MASK, new_fs_range, RES_LIS3DSH_CTRL_REG5);
  830.                 if(err < 0) {
  831.                         dev_err(&acc->client->dev, "update g range failed\n");
  832.                         return err;
  833.                 }
  834.                 else
  835.                         acc->sensitivity = sensitivity;
  836.         }

  837.         if(err < 0)
  838.                 dev_err(&acc->client->dev, "update g range not executed "
  839.                                                 "because the device is off\n");
  840.         return err;
  841. }


  842. static int lis3dsh_acc_update_odr(struct lis3dsh_acc_data *acc,
  843.                                                         int poll_interval_ms)
  844. {
  845.         int err = -1;
  846.         int i;
  847.         u8 new_odr;

  848.         /* Following, looks for the longest possible odr interval scrolling the
  849.          * odr_table vector from the end (shortest interval) backward (longest
  850.          * interval), to support the poll_interval requested by the system.
  851.          * It must be the longest interval lower then the poll interval.*/
  852.         for (i = ARRAY_SIZE(lis3dsh_acc_odr_table) - 1; i >= 0; i--) {
  853.                 if (lis3dsh_acc_odr_table[i].cutoff_ms <= poll_interval_ms)
  854.                         break;
  855.         }
  856.         new_odr = lis3dsh_acc_odr_table[i].mask;

  857.         /* If device is currently enabled, we need to write new
  858.          *  configuration out to it */
  859.         if (atomic_read(&acc->enabled)) {
  860.                 err = lis3dsh_acc_register_masked_update(acc,
  861.                         LIS3DSH_CTRL_REG4, LIS3DSH_ODR_MASK, new_odr,
  862.                                                         RES_LIS3DSH_CTRL_REG4);
  863.         }

  864.         if(err < 0)
  865.                 dev_err(&acc->client->dev, "update odr failed\n");
  866.         return err;
  867. }


  868. #ifdef DEBUG
  869. static int lis3dsh_acc_register_write(struct lis3dsh_acc_data *acc, u8 *buf,
  870.                 u8 reg_address, u8 new_value)
  871. {
  872.         int err = -1;

  873.         /* Sets configuration register at reg_address
  874.          *  NOTE: this is a straight overwrite  */
  875.                 buf[0] = reg_address;
  876.                 buf[1] = new_value;
  877.                 err = lis3dsh_acc_i2c_write(acc, buf, 1);
  878.                 if (err < 0)
  879.                         return err;
  880.         return err;
  881. }

  882. static int lis3dsh_acc_register_read(struct lis3dsh_acc_data *acc, u8 *buf,
  883.                 u8 reg_address)
  884. {

  885.         int err = -1;
  886.         buf[0] = (reg_address);
  887.         err = lis3dsh_acc_i2c_read(acc, buf, 1);
  888.         return err;
  889. }

  890. static int lis3dsh_acc_register_update(struct lis3dsh_acc_data *acc, u8 *buf,
  891.                 u8 reg_address, u8 mask, u8 new_bit_values)
  892. {
  893.         int err = -1;
  894.         u8 init_val;
  895.         u8 updated_val;
  896.         err = lis3dsh_acc_register_read(acc, buf, reg_address);
  897.         if (!(err < 0)) {
  898.                 init_val = buf[0];
  899.                 updated_val = ((mask & new_bit_values) | ((~mask) & init_val));
  900.                 err = lis3dsh_acc_register_write(acc, buf, reg_address,
  901.                                 updated_val);
  902.         }
  903.         return err;
  904. }
  905. #endif


  906. static int lis3dsh_acc_get_acceleration_data(struct lis3dsh_acc_data *acc,
  907.                 int *xyz)
  908. {
  909.         int err = -1;
  910.         /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
  911.         u8 acc_data[6];
  912.         /* x,y,z hardware data */
  913.         s32 hw_d[3] = { 0 };

  914.         acc_data[0] = (I2C_AUTO_INCREMENT | OUT_AXISDATA_REG);
  915.         err = lis3dsh_acc_i2c_read(acc, acc_data, 6);
  916.         if (err < 0)
  917.                 return err;

  918.         hw_d[0] = ((s16) ((acc_data[1] << 8) | acc_data[0]));
  919.         hw_d[1] = ((s16) ((acc_data[3] << 8) | acc_data[2]));
  920.         hw_d[2] = ((s16) ((acc_data[5] << 8) | acc_data[4]));

  921.         hw_d[0] = hw_d[0] * acc->sensitivity;
  922.         hw_d[1] = hw_d[1] * acc->sensitivity;
  923.         hw_d[2] = hw_d[2] * acc->sensitivity;


  924.         xyz[0] = ((acc->pdata->negate_x) ? (-hw_d[acc->pdata->axis_map_x])
  925.                    : (hw_d[acc->pdata->axis_map_x]));
  926.         xyz[1] = ((acc->pdata->negate_y) ? (-hw_d[acc->pdata->axis_map_y])
  927.                    : (hw_d[acc->pdata->axis_map_y]));
  928.         xyz[2] = ((acc->pdata->negate_z) ? (-hw_d[acc->pdata->axis_map_z])
  929.                    : (hw_d[acc->pdata->axis_map_z]));

  930.         pr_debug("%s read x=%d, y=%d, z=%d\n",
  931.                         LIS3DSH_ACC_DEV_NAME, xyz[0], xyz[1], xyz[2]);

  932.         return err;
  933. }

  934. static void lis3dsh_acc_report_values(struct lis3dsh_acc_data *acc,
  935.                                         int *xyz)
  936. {
  937.         input_report_abs(acc->input_dev, ABS_X, xyz[0]);
  938.         input_report_abs(acc->input_dev, ABS_Y, xyz[1]);
  939.         input_report_abs(acc->input_dev, ABS_Z, xyz[2]);
  940.         input_sync(acc->input_dev);
  941. }

  942. static int lis3dsh_acc_enable(struct lis3dsh_acc_data *acc)
  943. {
  944.         int err;

  945.         if (!atomic_cmpxchg(&acc->enabled, 0, 1)) {
  946.                 err = lis3dsh_acc_device_power_on(acc);
  947.                 if (err < 0) {
  948.                         atomic_set(&acc->enabled, 0);
  949.                         return err;
  950.                 }
  951.                 schedule_delayed_work(&acc->input_work,
  952.                         msecs_to_jiffies(acc->pdata->poll_interval));
  953.         }

  954.         return 0;
  955. }

  956. static int lis3dsh_acc_disable(struct lis3dsh_acc_data *acc)
  957. {
  958.         if (atomic_cmpxchg(&acc->enabled, 1, 0)) {
  959.                 cancel_delayed_work_sync(&acc->input_work);
  960.                 lis3dsh_acc_device_power_off(acc);
  961.         }

  962.         return 0;
  963. }

  964. static ssize_t attr_get_polling_rate(struct device *dev,
  965.                                         struct device_attribute *attr,
  966.                                                                 char *buf)
  967. {
  968.         int val;
  969.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  970.         mutex_lock(&acc->lock);
  971.         val = acc->pdata->poll_interval;
  972.         mutex_unlock(&acc->lock);
  973.         return sprintf(buf, "%d\n", val);
  974. }

  975. static ssize_t attr_set_polling_rate(struct device *dev,
  976.                                         struct device_attribute *attr,
  977.                                                 const char *buf, size_t size)
  978. {
  979.         int err;
  980.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  981.         unsigned long interval_ms;

  982.         if (strict_strtoul(buf, 10, &interval_ms))
  983.                 return -EINVAL;
  984.         if (!interval_ms)
  985.                 return -EINVAL;
  986.         mutex_lock(&acc->lock);
  987.         err = lis3dsh_acc_update_odr(acc, interval_ms);
  988.         if(err >= 0)
  989.         {
  990.                 acc->pdata->poll_interval = interval_ms;
  991.         }
  992.         mutex_unlock(&acc->lock);
  993.         return size;
  994. }

  995. static ssize_t attr_get_range(struct device *dev,
  996.                                 struct device_attribute *attr, char *buf)
  997. {
  998.         u8 val;
  999.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1000.         int range = 2;
  1001.         mutex_lock(&acc->lock);
  1002.         val = acc->pdata->fs_range ;
  1003.         switch(val) {
  1004.         case LIS3DSH_ACC_G_2G:
  1005.                 range = 2;
  1006.                 break;
  1007.         case LIS3DSH_ACC_G_4G:
  1008.                 range = 4;
  1009.                 break;
  1010.         case LIS3DSH_ACC_G_6G:
  1011.                 range = 6;
  1012.                 break;
  1013.         case LIS3DSH_ACC_G_8G:
  1014.                 range = 8;
  1015.                 break;
  1016.         case LIS3DSH_ACC_G_16G:
  1017.                 range = 16;
  1018.                 break;
  1019.         }
  1020.         mutex_unlock(&acc->lock);
  1021.         return sprintf(buf, "%d\n", range);
  1022. }

  1023. static ssize_t attr_set_range(struct device *dev,
  1024.                                 struct device_attribute *attr,
  1025.                                                 const char *buf, size_t size)
  1026. {
  1027.         int err;
  1028.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1029.         unsigned long val;
  1030.         u8 range;
  1031.         if (strict_strtoul(buf, 10, &val))
  1032.                 return -EINVAL;

  1033.         switch(val) {
  1034.                 case 2:
  1035.                         range = LIS3DSH_ACC_G_2G;
  1036.                         break;
  1037.                 case 4:
  1038.                         range = LIS3DSH_ACC_G_4G;
  1039.                         break;
  1040.                 case 6:
  1041.                         range = LIS3DSH_ACC_G_6G;
  1042.                         break;
  1043.                 case 8:
  1044.                         range = LIS3DSH_ACC_G_8G;
  1045.                         break;
  1046.                 case 16:
  1047.                         range = LIS3DSH_ACC_G_16G;
  1048.                         break;
  1049.                 default:
  1050.                         return -1;
  1051.         }

  1052.         mutex_lock(&acc->lock);
  1053.         err = lis3dsh_acc_update_fs_range(acc, range);
  1054.         if(err >= 0)
  1055.         {
  1056.                 acc->pdata->fs_range = range;
  1057.         }
  1058.         mutex_unlock(&acc->lock);
  1059.         return size;
  1060. }

  1061. static ssize_t attr_get_enable(struct device *dev,
  1062.                                 struct device_attribute *attr, char *buf)
  1063. {
  1064.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1065.         int val = atomic_read(&acc->enabled);
  1066.         return sprintf(buf, "%d\n", val);
  1067. }

  1068. static ssize_t attr_set_enable(struct device *dev,
  1069.                                 struct device_attribute *attr,
  1070.                                                 const char *buf, size_t size)
  1071. {
  1072.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1073.         unsigned long val;

  1074.         if (strict_strtoul(buf, 10, &val))
  1075.                 return -EINVAL;

  1076.         if (val)
  1077.                 lis3dsh_acc_enable(acc);
  1078.         else
  1079.                 lis3dsh_acc_disable(acc);

  1080.         return size;
  1081. }

  1082. static int lis3dsh_acc_state_progrs_enable_control(
  1083.                                 struct lis3dsh_acc_data *acc, u8 settings)
  1084. {
  1085.         u8 val1, val2;
  1086.         int err = -1;
  1087.         //settings = settings & 0x03;

  1088.         switch ( settings ) {
  1089.         case LIS3DSH_SM1_DIS_SM2_DIS:
  1090.                 val1 = LIS3DSH_SM1_EN_OFF;
  1091.                 val2 = LIS3DSH_SM2_EN_OFF;
  1092.                 break;
  1093.         case LIS3DSH_SM1_DIS_SM2_EN:
  1094.                 val1 = LIS3DSH_SM1_EN_OFF;
  1095.                 val2 = LIS3DSH_SM2_EN_ON;
  1096.                 break;
  1097.         case LIS3DSH_SM1_EN_SM2_DIS:
  1098.                 val1 = LIS3DSH_SM1_EN_ON;
  1099.                 val2 = LIS3DSH_SM2_EN_OFF;
  1100.                 break;
  1101.         case LIS3DSH_SM1_EN_SM2_EN:
  1102.                 val1 = LIS3DSH_SM1_EN_ON;
  1103.                 val2 = LIS3DSH_SM2_EN_ON;
  1104.                 break;
  1105.         default :
  1106.                 pr_err("invalid state program setting : 0x%02x\n",settings);
  1107.                 return err;
  1108.         }
  1109.         err = lis3dsh_acc_register_masked_update(acc,
  1110.                 LIS3DSH_CTRL_REG1, LIS3DSH_SM1_EN_MASK, val1,
  1111.                                                         RES_LIS3DSH_CTRL_REG1);
  1112.         if (err < 0 )
  1113.                 return err;

  1114.         err = lis3dsh_acc_register_masked_update(acc,
  1115.                 LIS3DSH_CTRL_REG2, LIS3DSH_SM2_EN_MASK, val2,
  1116.                                                         RES_LIS3DSH_CTRL_REG2);
  1117.         if (err < 0 )
  1118.                         return err;
  1119.         acc->stateprogs_enable_setting = settings;

  1120.         pr_debug("state program setting : 0x%02x\n",
  1121.                                                 acc->stateprogs_enable_setting);


  1122.         return err;
  1123. }

  1124. static ssize_t attr_set_enable_state_prog(struct device *dev,
  1125.                 struct device_attribute *attr,        const char *buf, size_t size)
  1126. {
  1127.         int err = -1;
  1128.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1129.         long val=0;

  1130.         if (strict_strtoul(buf, 16, &val))
  1131.                 return -EINVAL;


  1132.         if ( val < 0x00 || val > LIS3DSH_SM1_EN_SM2_EN){
  1133.                 pr_warn("invalid state program setting, val: %ld\n",val);
  1134.                 return -EINVAL;
  1135.         }

  1136.         mutex_lock(&acc->lock);
  1137.         err = lis3dsh_acc_state_progrs_enable_control(acc, val);
  1138.         mutex_unlock(&acc->lock);
  1139.         if (err < 0)
  1140.                 return err;
  1141.         return size;
  1142. }

  1143. static ssize_t attr_get_enable_state_prog(struct device *dev,
  1144.                 struct device_attribute *attr,        char *buf)
  1145. {
  1146.         u8 val;
  1147.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1148.         mutex_lock(&acc->lock);
  1149.         val = acc->stateprogs_enable_setting;
  1150.         mutex_unlock(&acc->lock);
  1151.         return sprintf(buf, "0x%02x\n", val);
  1152. }




  1153. #ifdef DEBUG
  1154. /* PAY ATTENTION: These DEBUG funtions don't manage resume_state */
  1155. static ssize_t attr_reg_set(struct device *dev, struct device_attribute *attr,
  1156.                                 const char *buf, size_t size)
  1157. {
  1158.         int rc;
  1159.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1160.         u8 x[2];
  1161.         unsigned long val;

  1162.         if (strict_strtoul(buf, 16, &val))
  1163.                 return -EINVAL;
  1164.         mutex_lock(&acc->lock);
  1165.         x[0] = acc->reg_addr;
  1166.         mutex_unlock(&acc->lock);
  1167.         x[1] = val;
  1168.         rc = lis3dsh_acc_i2c_write(acc, x, 1);
  1169.         /*TODO: error need to be managed */
  1170.         return size;
  1171. }

  1172. static ssize_t attr_reg_get(struct device *dev, struct device_attribute *attr,
  1173.                                 char *buf)
  1174. {
  1175.         ssize_t ret;
  1176.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1177.         int rc;
  1178.         u8 data;

  1179.         mutex_lock(&acc->lock);
  1180.         data = acc->reg_addr;
  1181.         mutex_unlock(&acc->lock);
  1182.         rc = lis3dsh_acc_i2c_read(acc, &data, 1);
  1183.         /*TODO: error need to be managed */
  1184.         ret = sprintf(buf, "0x%02x\n", data);
  1185.         return ret;
  1186. }

  1187. static ssize_t attr_addr_set(struct device *dev, struct device_attribute *attr,
  1188.                                 const char *buf, size_t size)
  1189. {
  1190.         struct lis3dsh_acc_data *acc = dev_get_drvdata(dev);
  1191.         unsigned long val;
  1192.         if (strict_strtoul(buf, 16, &val))
  1193.                 return -EINVAL;
  1194.         mutex_lock(&acc->lock);
  1195.         acc->reg_addr = val;
  1196.         mutex_unlock(&acc->lock);
  1197.         return size;
  1198. }
  1199. #endif

  1200. static struct device_attribute attributes[] = {

  1201.         __ATTR(poll_period_ms, 0664, attr_get_polling_rate,
  1202.                                                         attr_set_polling_rate),
  1203.         __ATTR(range, 0664, attr_get_range, attr_set_range),
  1204.         __ATTR(enable_device, 0664, attr_get_enable, attr_set_enable),
  1205.         __ATTR(enable_state_prog, 0664, attr_get_enable_state_prog,
  1206.                                                 attr_set_enable_state_prog),
  1207. #ifdef DEBUG
  1208.         __ATTR(reg_value, 0600, attr_reg_get, attr_reg_set),
  1209.         __ATTR(reg_addr, 0200, NULL, attr_addr_set),
  1210. #endif
  1211. };

  1212. static int create_sysfs_interfaces(struct device *dev)
  1213. {
  1214.         int i;
  1215.         for (i = 0; i < ARRAY_SIZE(attributes); i++)
  1216.                 if (device_create_file(dev, attributes + i))
  1217.                         goto error;
  1218.         return 0;

  1219. error:
  1220.         for ( ; i >= 0; i--)
  1221.                 device_remove_file(dev, attributes + i);
  1222.         dev_err(dev, "%s:Unable to create interface\n", __func__);
  1223.         return -1;
  1224. }

  1225. static int remove_sysfs_interfaces(struct device *dev)
  1226. {
  1227.         int i;
  1228.         for (i = 0; i < ARRAY_SIZE(attributes); i++)
  1229.                 device_remove_file(dev, attributes + i);
  1230.         return 0;
  1231. }

  1232. static void lis3dsh_acc_input_work_func(struct work_struct *work)
  1233. {
  1234.         struct lis3dsh_acc_data *acc;

  1235.         int xyz[3] = { 0 };
  1236.         int err;

  1237.         acc = container_of((struct delayed_work *)work,
  1238.                         struct lis3dsh_acc_data, input_work);

  1239.         mutex_lock(&acc->lock);
  1240.         err = lis3dsh_acc_get_acceleration_data(acc, xyz);
  1241.         if (err < 0)
  1242.                 dev_err(&acc->client->dev, "get_acceleration_data failed\n");
  1243.         else
  1244.                 lis3dsh_acc_report_values(acc, xyz);

  1245.         schedule_delayed_work(&acc->input_work, msecs_to_jiffies(
  1246.                         acc->pdata->poll_interval));
  1247.         mutex_unlock(&acc->lock);
  1248. }

  1249. int lis3dsh_acc_input_open(struct input_dev *input)
  1250. {
  1251.         struct lis3dsh_acc_data *acc = input_get_drvdata(input);

  1252.         return lis3dsh_acc_enable(acc);
  1253. }

  1254. void lis3dsh_acc_input_close(struct input_dev *dev)
  1255. {
  1256.         struct lis3dsh_acc_data *acc = input_get_drvdata(dev);

  1257.         lis3dsh_acc_disable(acc);
  1258. }

  1259. static int lis3dsh_acc_validate_pdata(struct lis3dsh_acc_data *acc)
  1260. {
  1261.         acc->pdata->poll_interval = max(acc->pdata->poll_interval,
  1262.                         acc->pdata->min_interval);

  1263.         if (acc->pdata->axis_map_x > 2 ||
  1264.                 acc->pdata->axis_map_y > 2 ||
  1265.                  acc->pdata->axis_map_z > 2) {
  1266.                 dev_err(&acc->client->dev, "invalid axis_map value "
  1267.                         "x:%u y:%u z%u\n", acc->pdata->axis_map_x,
  1268.                                 acc->pdata->axis_map_y, acc->pdata->axis_map_z);
  1269.                 return -EINVAL;
  1270.         }

  1271.         /* Only allow 0 and 1 for negation boolean flag */
  1272.         if (acc->pdata->negate_x > 1 || acc->pdata->negate_y > 1
  1273.                         || acc->pdata->negate_z > 1) {
  1274.                 dev_err(&acc->client->dev, "invalid negate value "
  1275.                         "x:%u y:%u z:%u\n", acc->pdata->negate_x,
  1276.                                 acc->pdata->negate_y, acc->pdata->negate_z);
  1277.                 return -EINVAL;
  1278.         }

  1279.         /* Enforce minimum polling interval */
  1280.         if (acc->pdata->poll_interval < acc->pdata->min_interval) {
  1281.                 dev_err(&acc->client->dev, "minimum poll interval violated\n");
  1282.                 return -EINVAL;
  1283.         }

  1284.         return 0;
  1285. }

  1286. static int lis3dsh_acc_input_init(struct lis3dsh_acc_data *acc)
  1287. {
  1288.         int err;

  1289.         INIT_DELAYED_WORK(&acc->input_work, lis3dsh_acc_input_work_func);
  1290.         acc->input_dev = input_allocate_device();
  1291.         if (!acc->input_dev) {
  1292.                 err = -ENOMEM;
  1293.                 dev_err(&acc->client->dev, "input device allocation failed\n");
  1294.                 goto err0;
  1295.         }

  1296.         acc->input_dev->open = lis3dsh_acc_input_open;
  1297.         acc->input_dev->close = lis3dsh_acc_input_close;
  1298.         acc->input_dev->name = LIS3DSH_ACC_DEV_NAME;

  1299.         acc->input_dev->id.bustype = BUS_I2C;
  1300.         acc->input_dev->dev.parent = &acc->client->dev;

  1301.         input_set_drvdata(acc->input_dev, acc);

  1302.         set_bit(EV_ABS, acc->input_dev->evbit);
  1303.         /*        next is used for interruptA sources data if the case */
  1304.         set_bit(ABS_MISC, acc->input_dev->absbit);
  1305.         /*        next is used for interruptB sources data if the case */
  1306.         set_bit(ABS_WHEEL, acc->input_dev->absbit);

  1307.         input_set_abs_params(acc->input_dev, ABS_X, -G_MAX, G_MAX, 0, 0);
  1308.         input_set_abs_params(acc->input_dev, ABS_Y, -G_MAX, G_MAX, 0, 0);
  1309.         input_set_abs_params(acc->input_dev, ABS_Z, -G_MAX, G_MAX, 0, 0);
  1310.         /*        next is used for interruptA sources data if the case */
  1311. //input_set_abs_params(acc->input_dev, ABS_MISC, INT_MIN, INT_MAX, 0, 0);
  1312.         /*        next is used for interruptB sources data if the case */
  1313. //input_set_abs_params(acc->input_dev, ABS_WHEEL, INT_MIN, INT_MAX, 0, 0);


  1314.         err = input_register_device(acc->input_dev);
  1315.         if (err) {
  1316.                 dev_err(&acc->client->dev,
  1317.                                 "unable to register input device %s\n",
  1318.                                 acc->input_dev->name);
  1319.                 goto err1;
  1320.         }

  1321.         return 0;

  1322. err1:
  1323.         input_free_device(acc->input_dev);
  1324. err0:
  1325.         return err;
  1326. }

  1327. static void lis3dsh_acc_input_cleanup(struct lis3dsh_acc_data *acc)
  1328. {
  1329.         input_unregister_device(acc->input_dev);
  1330.         input_free_device(acc->input_dev);
  1331. }

  1332. static int lis3dsh_acc_probe(struct i2c_client *client,
  1333.                 const struct i2c_device_id *id)
  1334. {

  1335.         struct lis3dsh_acc_data *acc;

  1336.         u32 smbus_func = I2C_FUNC_SMBUS_BYTE_DATA |
  1337.                         I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK ;

  1338.         int err = -1;

  1339.         dev_info(&client->dev, "probe start.\n");

  1340.         acc = kzalloc(sizeof(struct lis3dsh_acc_data), GFP_KERNEL);
  1341.         if (acc == NULL) {
  1342.                 err = -ENOMEM;
  1343.                 dev_err(&client->dev,
  1344.                                 "failed to allocate memory for module data: "
  1345.                                         "%d\n", err);
  1346.                 goto exit_check_functionality_failed;
  1347.         }

  1348.         /* Support for both I2C and SMBUS adapter interfaces. */
  1349.         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  1350.                 dev_warn(&client->dev, "client not i2c capable\n");
  1351.                 if (i2c_check_functionality(client->adapter, smbus_func)){
  1352.                         acc->use_smbus = 1;
  1353.                         dev_warn(&client->dev, "client using SMBUS\n");
  1354.                 } else {
  1355.                         err = -ENODEV;
  1356.                         dev_err(&client->dev, "client nor SMBUS capable\n");
  1357.                         acc->use_smbus = 0;
  1358.                         goto exit_check_functionality_failed;
  1359.                 }
  1360.         } else {
  1361.                 acc->use_smbus = 0;
  1362.         }

  1363.         mutex_init(&acc->lock);
  1364.         mutex_lock(&acc->lock);

  1365.         acc->client = client;
  1366.         i2c_set_clientdata(client, acc);

  1367.         acc->pdata = kmalloc(sizeof(*acc->pdata), GFP_KERNEL);
  1368.         if (acc->pdata == NULL) {
  1369.                 err = -ENOMEM;
  1370.                 dev_err(&client->dev,
  1371.                                 "failed to allocate memory for pdata: %d\n",
  1372.                                 err);
  1373.                 goto err_mutexunlock;
  1374.         }

  1375.         if(client->dev.platform_data == NULL) {
  1376.                 default_lis3dsh_acc_pdata.gpio_int1 = int1_gpio;
  1377.                 default_lis3dsh_acc_pdata.gpio_int2 = int2_gpio;
  1378.                 memcpy(acc->pdata, &default_lis3dsh_acc_pdata,
  1379.                                                         sizeof(*acc->pdata));
  1380.                 dev_info(&client->dev, "using default platform_data\n");
  1381.         } else {
  1382.                 memcpy(acc->pdata, client->dev.platform_data,
  1383.                                                         sizeof(*acc->pdata));
  1384.         }

  1385.         err = lis3dsh_acc_validate_pdata(acc);
  1386.         if (err < 0) {
  1387.                 dev_err(&client->dev, "failed to validate platform data\n");
  1388.                 goto exit_kfree_pdata;
  1389.         }

  1390.         if (acc->pdata->init) {
  1391.                 err = acc->pdata->init();
  1392.                 if (err < 0) {
  1393.                         dev_err(&client->dev, "init failed: %d\n", err);
  1394.                         goto err_pdata_init;
  1395.                 }
  1396.         }

  1397.         if(acc->pdata->gpio_int1 >= 0){
  1398.                 acc->irq1 = gpio_to_irq(acc->pdata->gpio_int1);
  1399.                 pr_info("%s: %s has set irq1 to irq: %d "
  1400.                                                         "mapped on gpio:%d\n",
  1401.                         LIS3DSH_ACC_DEV_NAME, __func__, acc->irq1,
  1402.                                                         acc->pdata->gpio_int1);
  1403.         }

  1404.         if(acc->pdata->gpio_int2 >= 0){
  1405.                 acc->irq2 = gpio_to_irq(acc->pdata->gpio_int2);
  1406.                 pr_info("%s: %s has set irq2 to irq: %d "
  1407.                                                         "mapped on gpio:%d\n",
  1408.                         LIS3DSH_ACC_DEV_NAME, __func__, acc->irq2,
  1409.                                                         acc->pdata->gpio_int2);
  1410.         }

  1411.         /* resume state init config */
  1412.         memset(acc->resume_state, 0, ARRAY_SIZE(acc->resume_state));
  1413.         lis3dsh_acc_set_init_register_values(acc);
  1414.         //init state program1 and params
  1415.         lis3dsh_acc_set_init_statepr1_param(acc);
  1416.         lis3dsh_acc_set_init_statepr1_inst(acc);
  1417.         //init state program2  and params
  1418.         lis3dsh_acc_set_init_statepr2_param(acc);
  1419.         lis3dsh_acc_set_init_statepr2_inst(acc);

  1420.         err = lis3dsh_acc_device_power_on(acc);
  1421.         if (err < 0) {
  1422.                 dev_err(&client->dev, "power on failed: %d\n", err);
  1423.                 goto err_pdata_init;
  1424.         }

  1425.         atomic_set(&acc->enabled, 1);

  1426.         err = lis3dsh_acc_update_fs_range(acc, acc->pdata->fs_range);
  1427.         if (err < 0) {
  1428.                 dev_err(&client->dev, "update_fs_range failed\n");
  1429.                 goto  err_power_off;
  1430.         }

  1431.         err = lis3dsh_acc_update_odr(acc, acc->pdata->poll_interval);
  1432.         if (err < 0) {
  1433.                 dev_err(&client->dev, "update_odr failed\n");
  1434.                 goto  err_power_off;
  1435.         }

  1436.         err = lis3dsh_acc_input_init(acc);
  1437.         if (err < 0) {
  1438.                 dev_err(&client->dev, "input init failed\n");
  1439.                 goto err_power_off;
  1440.         }


  1441.         err = create_sysfs_interfaces(&client->dev);
  1442.         if (err < 0) {
  1443.                 dev_err(&client->dev,
  1444.                    "device LIS3DSH_ACC_DEV_NAME sysfs register failed\n");
  1445.                 goto err_input_cleanup;
  1446.         }

  1447.         lis3dsh_acc_device_power_off(acc);

  1448.         /* As default, do not report information */
  1449.         atomic_set(&acc->enabled, 0);

  1450.         if(acc->pdata->gpio_int1 >= 0){
  1451.                 INIT_WORK(&acc->irq1_work, lis3dsh_acc_irq1_work_func);
  1452.                 acc->irq1_work_queue =
  1453.                         create_singlethread_workqueue("lis3dsh_acc_wq1");
  1454.                 if (!acc->irq1_work_queue) {
  1455.                         err = -ENOMEM;
  1456.                         dev_err(&client->dev,
  1457.                                         "cannot create work queue1: %d\n", err);
  1458.                         goto err_remove_sysfs_int;
  1459.                 }
  1460.                 err = request_irq(acc->irq1, lis3dsh_acc_isr1,
  1461.                                 IRQF_TRIGGER_RISING, "lis3dsh_acc_irq1", acc);
  1462.                 if (err < 0) {
  1463.                         dev_err(&client->dev, "request irq1 failed: %d\n", err);
  1464.                         goto err_destoyworkqueue1;
  1465.                 }
  1466.                 disable_irq_nosync(acc->irq1);
  1467.         }

  1468.         if(acc->pdata->gpio_int2 >= 0){
  1469.                 INIT_WORK(&acc->irq2_work, lis3dsh_acc_irq2_work_func);
  1470.                 acc->irq2_work_queue =
  1471.                         create_singlethread_workqueue("lis3dsh_acc_wq2");
  1472.                 if (!acc->irq2_work_queue) {
  1473.                         err = -ENOMEM;
  1474.                         dev_err(&client->dev,
  1475.                                         "cannot create work queue2: %d\n", err);
  1476.                         goto err_free_irq1;
  1477.                 }
  1478.                 err = request_irq(acc->irq2, lis3dsh_acc_isr2,
  1479.                                 IRQF_TRIGGER_RISING, "lis3dsh_acc_irq2", acc);
  1480.                 if (err < 0) {
  1481.                         dev_err(&client->dev, "request irq2 failed: %d\n", err);
  1482.                         goto err_destoyworkqueue2;
  1483.                 }
  1484.                 disable_irq_nosync(acc->irq2);
  1485.         }



  1486.         mutex_unlock(&acc->lock);

  1487.         dev_info(&client->dev, "%s: probed\n", LIS3DSH_ACC_DEV_NAME);

  1488.         return 0;

  1489. err_destoyworkqueue2:
  1490.         if(acc->pdata->gpio_int2 >= 0)
  1491.                 destroy_workqueue(acc->irq2_work_queue);
  1492. err_free_irq1:
  1493.         free_irq(acc->irq1, acc);
  1494. err_destoyworkqueue1:
  1495.         if(acc->pdata->gpio_int1 >= 0)
  1496.                 destroy_workqueue(acc->irq1_work_queue);
  1497. err_remove_sysfs_int:
  1498.         remove_sysfs_interfaces(&client->dev);
  1499. err_input_cleanup:
  1500.         lis3dsh_acc_input_cleanup(acc);
  1501. err_power_off:
  1502.         lis3dsh_acc_device_power_off(acc);
  1503. err_pdata_init:
  1504.         if (acc->pdata->exit)
  1505.                 acc->pdata->exit();
  1506. exit_kfree_pdata:
  1507.         kfree(acc->pdata);
  1508. err_mutexunlock:
  1509.         mutex_unlock(&acc->lock);
  1510. //err_freedata:
  1511.         kfree(acc);
  1512. exit_check_functionality_failed:
  1513.         pr_err("%s: Driver Init failed\n", LIS3DSH_ACC_DEV_NAME);
  1514.         return err;
  1515. }

  1516. static int __devexit lis3dsh_acc_remove(struct i2c_client *client)
  1517. {
  1518.         struct lis3dsh_acc_data *acc = i2c_get_clientdata(client);

  1519.         if(acc->pdata->gpio_int1 >= 0){
  1520.                 free_irq(acc->irq1, acc);
  1521.                 gpio_free(acc->pdata->gpio_int1);
  1522.                 destroy_workqueue(acc->irq1_work_queue);
  1523.         }

  1524.         if(acc->pdata->gpio_int2 >= 0){
  1525.                 free_irq(acc->irq2, acc);
  1526.                 gpio_free(acc->pdata->gpio_int2);
  1527.                 destroy_workqueue(acc->irq2_work_queue);
  1528.         }

  1529.         if (atomic_cmpxchg(&acc->enabled, 1, 0))
  1530.                         cancel_delayed_work_sync(&acc->input_work);

  1531.         lis3dsh_acc_device_power_off(acc);
  1532.         lis3dsh_acc_input_cleanup(acc);
  1533.         remove_sysfs_interfaces(&client->dev);

  1534.         if (acc->pdata->exit)
  1535.                 acc->pdata->exit();

  1536.         kfree(acc->pdata);
  1537.         kfree(acc);

  1538.         return 0;
  1539. }

  1540. #ifdef CONFIG_PM
  1541. static int lis3dsh_acc_resume(struct i2c_client *client)
  1542. {
  1543.         struct lis3dsh_acc_data *acc = i2c_get_clientdata(client);

  1544.         if (acc->on_before_suspend)
  1545.                 return lis3dsh_acc_enable(acc);
  1546.         return 0;
  1547. }

  1548. static int lis3dsh_acc_suspend(struct i2c_client *client, pm_message_t mesg)
  1549. {
  1550.         struct lis3dsh_acc_data *acc = i2c_get_clientdata(client);

  1551.         acc->on_before_suspend = atomic_read(&acc->enabled);
  1552.         return lis3dsh_acc_disable(acc);
  1553. }
  1554. #else
  1555. #define lis3dsh_acc_suspend        NULL
  1556. #define lis3dsh_acc_resume        NULL
  1557. #endif /* CONFIG_PM */

  1558. static const struct i2c_device_id lis3dsh_acc_id[]
  1559.                 = { { LIS3DSH_ACC_DEV_NAME, 0 }, { }, };

  1560. MODULE_DEVICE_TABLE(i2c, lis3dsh_acc_id);

  1561. static struct i2c_driver lis3dsh_acc_driver = {
  1562.         .driver = {
  1563.                         .owner = THIS_MODULE,
  1564.                         .name = LIS3DSH_ACC_DEV_NAME,
  1565.                   },
  1566.         .probe = lis3dsh_acc_probe,
  1567.         .remove = __devexit_p(lis3dsh_acc_remove),
  1568.         .suspend = lis3dsh_acc_suspend,
  1569.         .resume = lis3dsh_acc_resume,
  1570.         .id_table = lis3dsh_acc_id,
  1571. };

  1572. static int __init lis3dsh_acc_init(void)
  1573. {
  1574.         pr_info("%s accelerometer driver: init\n", LIS3DSH_ACC_DEV_NAME);
  1575.         return i2c_add_driver(&lis3dsh_acc_driver);
  1576. }

  1577. static void __exit lis3dsh_acc_exit(void)
  1578. {
  1579.         pr_info("%s accelerometer driver: exit\n", LIS3DSH_ACC_DEV_NAME);
  1580.         i2c_del_driver(&lis3dsh_acc_driver);
  1581.         return;
  1582. }

  1583. module_init(lis3dsh_acc_init);
  1584. module_exit(lis3dsh_acc_exit);

  1585. MODULE_DESCRIPTION("lis3dsh accelerometer driver");
  1586. MODULE_AUTHOR("Matteo Dameno, Denis Ciocca, STMicroelectronics");
  1587. MODULE_LICENSE("GPL");

复制代码

虾扯蛋


回复

使用道具 举报

4

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-11-20 10:24 | 显示全部楼层


回复

使用道具 举报

1637

TA的帖子

4

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2017-11-21 09:41 | 显示全部楼层
找到宝物了,


回复

使用道具 举报

13

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-11-24 14:39 | 显示全部楼层
太牛了,多谢分享!


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-1 16:50 | 显示全部楼层
厉害了,我的哥,谢谢


回复

使用道具 举报

10

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-12-16 11:16 | 显示全部楼层
很好,很好。。


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-3-9 19:03 | 显示全部楼层
问一下各位大神你们这个驱动文件在哪下的?在官网我怎么找不见


回复

使用道具 举报

9

TA的帖子

3

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-3-12 08:31 | 显示全部楼层
太牛了,多谢分享!


回复

使用道具 举报

5

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-3-22 17:00 | 显示全部楼层

请教各位,

最少硬件与编程来实现羽球拍挥拍路径之侦测,

LSM6DS3是否可行? LSM6DS3内置6D 方向检测与大幅运动检测,

或者其他传感器可行?求帮助。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-3-22 00:08 , Processed in 0.561265 second(s), 19 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表