mpu6050.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139
  1. /* MPU6050 motion sensor driver
  2. *
  3. * This software is licensed under the terms of the GNU General Public
  4. * License version 2, as published by the Free Software Foundation, and
  5. * may be copied, distributed, and modified under those terms.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <cust_acc.h>
  14. #include "mpu6050.h"
  15. #include <accel.h>
  16. #include <hwmsensor.h>
  17. static DEFINE_MUTEX(mpu6050_i2c_mutex);
  18. /* Maintain cust info here */
  19. struct acc_hw accel_cust;
  20. static struct acc_hw *hw = &accel_cust;
  21. /* For driver get cust info */
  22. struct acc_hw *get_cust_acc(void)
  23. {
  24. return &accel_cust;
  25. }
  26. /*----------------------------------------------------------------------------*/
  27. /*#define DEBUG 1*/
  28. /*----------------------------------------------------------------------------*/
  29. #define CONFIG_MPU6050_LOWPASS /*apply low pass filter on output */
  30. #define SW_CALIBRATION
  31. /*----------------------------------------------------------------------------*/
  32. #define MPU6050_AXIS_X 0
  33. #define MPU6050_AXIS_Y 1
  34. #define MPU6050_AXIS_Z 2
  35. #define MPU6050_AXES_NUM 3
  36. #define MPU6050_DATA_LEN 6
  37. #define MPU6050_DEV_NAME "MPU6050G" /* name must different with gyro mpu6050 */
  38. /*----------------------------------------------------------------------------*/
  39. static const struct i2c_device_id mpu6050_i2c_id[] = { {MPU6050_DEV_NAME, 0}, {} };
  40. /*----------------------------------------------------------------------------*/
  41. static int mpu6050_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
  42. static int mpu6050_i2c_remove(struct i2c_client *client);
  43. static int mpu6050_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
  44. #ifndef USE_EARLY_SUSPEND
  45. static int mpu6050_suspend(struct i2c_client *client, pm_message_t msg);
  46. static int mpu6050_resume(struct i2c_client *client);
  47. #endif
  48. static int mpu6050_local_init(void);
  49. static int mpu6050_remove(void);
  50. static int mpu6050_init_flag = -1; /*0<==>OK -1 <==> fail*/
  51. static struct acc_init_info mpu6050_init_info = {
  52. .name = "mpu6050g",
  53. .init = mpu6050_local_init,
  54. .uninit = mpu6050_remove,
  55. };
  56. /*----------------------------------------------------------------------------*/
  57. enum {
  58. MPU6050_TRC_FILTER = 0x01,
  59. MPU6050_TRC_RAWDATA = 0x02,
  60. MPU6050_TRC_IOCTL = 0x04,
  61. MPU6050_TRC_CALI = 0X08,
  62. MPU6050_TRC_INFO = 0X10,
  63. };
  64. /*----------------------------------------------------------------------------*/
  65. struct scale_factor {
  66. u8 whole;
  67. u8 fraction;
  68. };
  69. /*----------------------------------------------------------------------------*/
  70. struct data_resolution {
  71. struct scale_factor scalefactor;
  72. int sensitivity;
  73. };
  74. /*----------------------------------------------------------------------------*/
  75. #define C_MAX_FIR_LENGTH (32)
  76. /*----------------------------------------------------------------------------*/
  77. struct data_filter {
  78. s16 raw[C_MAX_FIR_LENGTH][MPU6050_AXES_NUM];
  79. int sum[MPU6050_AXES_NUM];
  80. int num;
  81. int idx;
  82. };
  83. /*----------------------------------------------------------------------------*/
  84. struct mpu6050_i2c_data {
  85. struct i2c_client *client;
  86. struct acc_hw *hw;
  87. struct hwmsen_convert cvt;
  88. /*misc */
  89. struct data_resolution *reso;
  90. atomic_t trace;
  91. atomic_t suspend;
  92. atomic_t selftest;
  93. atomic_t filter;
  94. s16 cali_sw[MPU6050_AXES_NUM + 1];
  95. /*data */
  96. s8 offset[MPU6050_AXES_NUM + 1]; /*+1: for 4-byte alignment */
  97. s16 data[MPU6050_AXES_NUM + 1];
  98. #if defined(CONFIG_MPU6050_LOWPASS)
  99. atomic_t firlen;
  100. atomic_t fir_en;
  101. struct data_filter fir;
  102. #endif
  103. /*early suspend */
  104. #if defined(USE_EARLY_SUSPEND)
  105. struct early_suspend early_drv;
  106. #endif
  107. u8 bandwidth;
  108. };
  109. /*----------------------------------------------------------------------------*/
  110. #ifdef CONFIG_OF
  111. static const struct of_device_id accel_of_match[] = {
  112. {.compatible = "mediatek,gsensor"},
  113. {},
  114. };
  115. #endif
  116. static struct i2c_driver mpu6050g_i2c_driver = {
  117. .driver = {
  118. .name = MPU6050_DEV_NAME,
  119. #ifdef CONFIG_OF
  120. .of_match_table = accel_of_match,
  121. #endif
  122. },
  123. .probe = mpu6050_i2c_probe,
  124. .remove = mpu6050_i2c_remove,
  125. .detect = mpu6050_i2c_detect,
  126. #if !defined(USE_EARLY_SUSPEND)
  127. .suspend = mpu6050_suspend,
  128. .resume = mpu6050_resume,
  129. #endif
  130. .id_table = mpu6050_i2c_id,
  131. };
  132. /*----------------------------------------------------------------------------*/
  133. static struct i2c_client *mpu6050_i2c_client;
  134. static struct mpu6050_i2c_data *obj_i2c_data;
  135. static bool sensor_power;
  136. static struct GSENSOR_VECTOR3D gsensor_gain;
  137. static char selftestRes[8] = { 0 };
  138. /*----------------------------------------------------------------------------*/
  139. #define MPU6050G_DEBUG 0
  140. #define GSE_TAG "[Gsensor] "
  141. #define GSE_FUN(f) pr_debug(GSE_TAG"%s\n", __func__)
  142. #define GSE_ERR(fmt, args...) pr_err(GSE_TAG"%s %d : "fmt, __func__, __LINE__, ##args)
  143. #if MPU6050G_DEBUG
  144. #define GSE_LOG(fmt, args...) pr_debug(GSE_TAG fmt, ##args)
  145. #else
  146. #define GSE_LOG(fmt, args...)
  147. #endif
  148. /*----------------------------------------------------------------------------*/
  149. static struct data_resolution mpu6050_data_resolution[] = {
  150. /*8 combination by {FULL_RES,RANGE} */
  151. {{0, 6}, 16384}, /*+/-2g in 16-bit resolution: 0.06 mg/LSB */
  152. {{0, 12}, 8192}, /*+/-4g in 16-bit resolution: 0.12 mg/LSB */
  153. {{0, 24}, 4096}, /*+/-8g in 16-bit resolution: 0.24 mg/LSB */
  154. {{0, 5}, 2048}, /*+/-16g in 16-bit resolution: 0.49 mg/LSB */
  155. };
  156. /*----------------------------------------------------------------------------*/
  157. static struct data_resolution mpu6050_offset_resolution = { {0, 5}, 2048 };
  158. static unsigned int power_on;
  159. int MPU6050_gse_power(void)
  160. {
  161. return power_on;
  162. }
  163. EXPORT_SYMBOL(MPU6050_gse_power);
  164. int MPU6050_gse_mode(void)
  165. {
  166. return sensor_power;
  167. }
  168. EXPORT_SYMBOL(MPU6050_gse_mode);
  169. /*----------------------------------------------------------------------------*/
  170. static int mpu_i2c_read_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
  171. {
  172. int err;
  173. u8 beg = addr;
  174. struct i2c_msg msgs[2] = { {0}, {0} };
  175. mutex_lock(&mpu6050_i2c_mutex);
  176. msgs[0].addr = client->addr;
  177. msgs[0].flags = 0;
  178. msgs[0].len = 1;
  179. msgs[0].buf = &beg;
  180. msgs[1].addr = client->addr;
  181. msgs[1].flags = I2C_M_RD;
  182. msgs[1].len = len;
  183. msgs[1].buf = data;
  184. if (!client) {
  185. mutex_unlock(&mpu6050_i2c_mutex);
  186. return -EINVAL;
  187. } else if (len > C_I2C_FIFO_SIZE) {
  188. mutex_unlock(&mpu6050_i2c_mutex);
  189. GSE_ERR(" length %d exceeds %d\n", len, C_I2C_FIFO_SIZE);
  190. return -EINVAL;
  191. }
  192. err = i2c_transfer(client->adapter, msgs, sizeof(msgs)/sizeof(msgs[0]));
  193. if (err != 2) {
  194. GSE_ERR("i2c_transfer error: (%d %p %d) %d\n",
  195. addr, data, len, err);
  196. err = -EIO;
  197. } else {
  198. err = 0;
  199. }
  200. mutex_unlock(&mpu6050_i2c_mutex);
  201. return err;
  202. }
  203. static int mpu_i2c_write_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
  204. { /*because address also occupies one byte, the maximum length for write is 7 bytes*/
  205. int err, idx, num;
  206. char buf[C_I2C_FIFO_SIZE];
  207. err = 0;
  208. mutex_lock(&mpu6050_i2c_mutex);
  209. if (!client) {
  210. mutex_unlock(&mpu6050_i2c_mutex);
  211. return -EINVAL;
  212. } else if (len >= C_I2C_FIFO_SIZE) {
  213. mutex_unlock(&mpu6050_i2c_mutex);
  214. GSE_ERR(" length %d exceeds %d\n", len, C_I2C_FIFO_SIZE);
  215. return -EINVAL;
  216. }
  217. num = 0;
  218. buf[num++] = addr;
  219. for (idx = 0; idx < len; idx++)
  220. buf[num++] = data[idx];
  221. err = i2c_master_send(client, buf, num);
  222. if (err < 0) {
  223. mutex_unlock(&mpu6050_i2c_mutex);
  224. GSE_ERR("send command error!!\n");
  225. return -EFAULT;
  226. }
  227. mutex_unlock(&mpu6050_i2c_mutex);
  228. return err;
  229. }
  230. int MPU6050_hwmsen_read_block(u8 addr, u8 *buf, u8 len)
  231. {
  232. if (NULL == mpu6050_i2c_client) {
  233. GSE_ERR("MPU6050_hwmsen_read_block null ptr!!\n");
  234. return MPU6050_ERR_I2C;
  235. }
  236. return mpu_i2c_read_block(mpu6050_i2c_client, addr, buf, len);
  237. }
  238. EXPORT_SYMBOL(MPU6050_hwmsen_read_block);
  239. int MPU6050_hwmsen_write_block(u8 addr, u8 *buf, u8 len)
  240. {
  241. if (NULL == mpu6050_i2c_client) {
  242. GSE_ERR("MPU6050_hwmsen_write_block null ptr!!\n");
  243. return MPU6050_ERR_I2C;
  244. }
  245. return mpu_i2c_write_block(mpu6050_i2c_client, addr, buf, len);
  246. }
  247. EXPORT_SYMBOL(MPU6050_hwmsen_write_block);
  248. /*--------------------mpu6050 power control function----------------------------------*/
  249. static void MPU6050_power(struct acc_hw *hw, unsigned int on)
  250. {
  251. }
  252. /*----------------------------------------------------------------------------*/
  253. static int MPU6050_SetPowerMode(struct i2c_client *client, bool enable)
  254. {
  255. u8 databuf[2];
  256. int res = 0;
  257. /* u8 addr = MPU6050_REG_POWER_CTL; */
  258. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  259. if (enable == sensor_power) {
  260. GSE_LOG("Sensor power status is newest!\n");
  261. return MPU6050_SUCCESS;
  262. }
  263. res = mpu_i2c_read_block(client, MPU6050_REG_POWER_CTL, databuf, 0x1);
  264. if (res < 0)
  265. return MPU6050_ERR_I2C;
  266. databuf[0] &= ~MPU6050_SLEEP;
  267. if (enable == false) {
  268. if (MPU6050_gyro_mode() == false)
  269. databuf[0] |= MPU6050_SLEEP;
  270. } else {
  271. /* do nothing */
  272. }
  273. res = mpu_i2c_write_block(client, MPU6050_REG_POWER_CTL, databuf, 0x1);
  274. if (res < 0) {
  275. GSE_ERR("set power mode failed!\n");
  276. return MPU6050_ERR_I2C;
  277. } else if (atomic_read(&obj->trace) & MPU6050_TRC_INFO)
  278. GSE_LOG("set power mode ok %d!\n", databuf[0]);
  279. sensor_power = enable;
  280. return MPU6050_SUCCESS;
  281. }
  282. /*----------------------------------------------------------------------------*/
  283. static int MPU6050_SetDataResolution(struct mpu6050_i2c_data *obj)
  284. {
  285. int err;
  286. u8 dat, reso;
  287. err = mpu_i2c_read_block(obj->client, MPU6050_REG_DATA_FORMAT, &dat, 1);
  288. if (err) {
  289. GSE_ERR("write data format fail!!\n");
  290. return err;
  291. }
  292. /*the data_reso is combined by 3 bits: {FULL_RES, DATA_RANGE} */
  293. reso = 0x00;
  294. reso = (dat & MPU6050_RANGE_16G) >> 3;
  295. if (reso < sizeof(mpu6050_data_resolution) / sizeof(mpu6050_data_resolution[0])) {
  296. obj->reso = &mpu6050_data_resolution[reso];
  297. return 0;
  298. } else {
  299. return -EINVAL;
  300. }
  301. }
  302. /*----------------------------------------------------------------------------*/
  303. static int MPU6050_ReadData(struct i2c_client *client, s16 data[MPU6050_AXES_NUM])
  304. {
  305. struct mpu6050_i2c_data *priv = i2c_get_clientdata(client);
  306. u8 buf[MPU6050_DATA_LEN] = { 0 };
  307. int err = 0;
  308. if (NULL == client)
  309. return -EINVAL;
  310. {
  311. /* write then burst read */
  312. mpu_i2c_read_block(client, MPU6050_REG_DATAX0, buf, MPU6050_DATA_LEN);
  313. data[MPU6050_AXIS_X] = (s16) ((buf[MPU6050_AXIS_X * 2] << 8) |
  314. (buf[MPU6050_AXIS_X * 2 + 1]));
  315. data[MPU6050_AXIS_Y] = (s16) ((buf[MPU6050_AXIS_Y * 2] << 8) |
  316. (buf[MPU6050_AXIS_Y * 2 + 1]));
  317. data[MPU6050_AXIS_Z] = (s16) ((buf[MPU6050_AXIS_Z * 2] << 8) |
  318. (buf[MPU6050_AXIS_Z * 2 + 1]));
  319. if (atomic_read(&priv->trace) & MPU6050_TRC_RAWDATA) {
  320. GSE_LOG("[%08X %08X %08X] => [%5d %5d %5d]\n", data[MPU6050_AXIS_X],
  321. data[MPU6050_AXIS_Y], data[MPU6050_AXIS_Z], data[MPU6050_AXIS_X],
  322. data[MPU6050_AXIS_Y], data[MPU6050_AXIS_Z]);
  323. }
  324. #ifdef CONFIG_MPU6050_LOWPASS
  325. if (atomic_read(&priv->filter)) {
  326. if (atomic_read(&priv->fir_en) && !atomic_read(&priv->suspend)) {
  327. int idx, firlen = atomic_read(&priv->firlen);
  328. if (priv->fir.num < firlen) {
  329. priv->fir.raw[priv->fir.num][MPU6050_AXIS_X] = data[MPU6050_AXIS_X];
  330. priv->fir.raw[priv->fir.num][MPU6050_AXIS_Y] = data[MPU6050_AXIS_Y];
  331. priv->fir.raw[priv->fir.num][MPU6050_AXIS_Z] = data[MPU6050_AXIS_Z];
  332. priv->fir.sum[MPU6050_AXIS_X] += data[MPU6050_AXIS_X];
  333. priv->fir.sum[MPU6050_AXIS_Y] += data[MPU6050_AXIS_Y];
  334. priv->fir.sum[MPU6050_AXIS_Z] += data[MPU6050_AXIS_Z];
  335. if (atomic_read(&priv->trace) & MPU6050_TRC_FILTER) {
  336. GSE_LOG("add [%2d] [%5d %5d %5d] => [%5d %5d %5d]\n", priv->fir.num,
  337. priv->fir.raw[priv->fir.num][MPU6050_AXIS_X],
  338. priv->fir.raw[priv->fir.num][MPU6050_AXIS_Y],
  339. priv->fir.raw[priv->fir.num][MPU6050_AXIS_Z],
  340. priv->fir.sum[MPU6050_AXIS_X], priv->fir.sum[MPU6050_AXIS_Y],
  341. priv->fir.sum[MPU6050_AXIS_Z]);
  342. }
  343. priv->fir.num++;
  344. priv->fir.idx++;
  345. } else {
  346. idx = priv->fir.idx % firlen;
  347. priv->fir.sum[MPU6050_AXIS_X] -= priv->fir.raw[idx][MPU6050_AXIS_X];
  348. priv->fir.sum[MPU6050_AXIS_Y] -= priv->fir.raw[idx][MPU6050_AXIS_Y];
  349. priv->fir.sum[MPU6050_AXIS_Z] -= priv->fir.raw[idx][MPU6050_AXIS_Z];
  350. priv->fir.raw[idx][MPU6050_AXIS_X] = data[MPU6050_AXIS_X];
  351. priv->fir.raw[idx][MPU6050_AXIS_Y] = data[MPU6050_AXIS_Y];
  352. priv->fir.raw[idx][MPU6050_AXIS_Z] = data[MPU6050_AXIS_Z];
  353. priv->fir.sum[MPU6050_AXIS_X] += data[MPU6050_AXIS_X];
  354. priv->fir.sum[MPU6050_AXIS_Y] += data[MPU6050_AXIS_Y];
  355. priv->fir.sum[MPU6050_AXIS_Z] += data[MPU6050_AXIS_Z];
  356. priv->fir.idx++;
  357. data[MPU6050_AXIS_X] = priv->fir.sum[MPU6050_AXIS_X]/firlen;
  358. data[MPU6050_AXIS_Y] = priv->fir.sum[MPU6050_AXIS_Y]/firlen;
  359. data[MPU6050_AXIS_Z] = priv->fir.sum[MPU6050_AXIS_Z]/firlen;
  360. if (atomic_read(&priv->trace) & MPU6050_TRC_FILTER)
  361. GSE_LOG("add [%2d] [%5d %5d %5d] => [%5d %5d %5d] : [%5d %5d %5d]\n",
  362. idx,
  363. priv->fir.raw[idx][MPU6050_AXIS_X], priv->fir.raw[idx][MPU6050_AXIS_Y],
  364. priv->fir.raw[idx][MPU6050_AXIS_Z], priv->fir.sum[MPU6050_AXIS_X],
  365. priv->fir.sum[MPU6050_AXIS_Y], priv->fir.sum[MPU6050_AXIS_Z],
  366. data[MPU6050_AXIS_X], data[MPU6050_AXIS_Y], data[MPU6050_AXIS_Z]);
  367. }
  368. }
  369. }
  370. #endif
  371. }
  372. return err;
  373. }
  374. /*----------------------------------------------------------------------------*/
  375. static int MPU6050_ReadOffset(struct i2c_client *client, s8 ofs[MPU6050_AXES_NUM])
  376. {
  377. int err = 0;
  378. #ifdef SW_CALIBRATION
  379. ofs[0] = ofs[1] = ofs[2] = 0x0;
  380. #else
  381. err = mpu_i2c_read_block(client, MPU6050_REG_OFSX, ofs, MPU6050_AXES_NUM);
  382. if (err)
  383. GSE_ERR("error: %d\n", err);
  384. #endif
  385. /* GSE_LOG("offesx=%x, y=%x, z=%x",ofs[0],ofs[1],ofs[2]); */
  386. return err;
  387. }
  388. /*----------------------------------------------------------------------------*/
  389. static int MPU6050_ResetCalibration(struct i2c_client *client)
  390. {
  391. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  392. #ifndef SW_CALIBRATION
  393. s8 ofs[MPU6050_AXES_NUM] = { 0x00, 0x00, 0x00 };
  394. #endif
  395. int err = 0;
  396. #ifdef SW_CALIBRATION
  397. /* do not thing */
  398. #else
  399. err = hwmsen_write_block(client, MPU6050_REG_OFSX, ofs, MPU6050_AXES_NUM);
  400. if (err)
  401. GSE_ERR("error: %d\n", err);
  402. #endif
  403. memset(obj->cali_sw, 0x00, sizeof(obj->cali_sw));
  404. memset(obj->offset, 0x00, sizeof(obj->offset));
  405. return err;
  406. }
  407. /*----------------------------------------------------------------------------*/
  408. static int MPU6050_ReadCalibration(struct i2c_client *client, int dat[MPU6050_AXES_NUM])
  409. {
  410. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  411. #ifdef SW_CALIBRATION
  412. int mul;
  413. #else
  414. int err;
  415. #endif
  416. #ifdef SW_CALIBRATION
  417. mul = 0; /* only SW Calibration, disable HW Calibration */
  418. #else
  419. err = MPU6050_ReadOffset(client, obj->offset);
  420. if (err) {
  421. GSE_ERR("read offset fail, %d\n", err);
  422. return err;
  423. }
  424. mul = obj->reso->sensitivity / mpu6050_offset_resolution.sensitivity;
  425. #endif
  426. dat[obj->cvt.map[MPU6050_AXIS_X]] =
  427. obj->cvt.sign[MPU6050_AXIS_X]*(obj->offset[MPU6050_AXIS_X]*mul + obj->cali_sw[MPU6050_AXIS_X]);
  428. dat[obj->cvt.map[MPU6050_AXIS_Y]] =
  429. obj->cvt.sign[MPU6050_AXIS_Y]*(obj->offset[MPU6050_AXIS_Y]*mul + obj->cali_sw[MPU6050_AXIS_Y]);
  430. dat[obj->cvt.map[MPU6050_AXIS_Z]] =
  431. obj->cvt.sign[MPU6050_AXIS_Z]*(obj->offset[MPU6050_AXIS_Z]*mul + obj->cali_sw[MPU6050_AXIS_Z]);
  432. return 0;
  433. }
  434. /*----------------------------------------------------------------------------*/
  435. static int MPU6050_ReadCalibrationEx(struct i2c_client *client, int act[MPU6050_AXES_NUM],
  436. int raw[MPU6050_AXES_NUM])
  437. {
  438. /*raw: the raw calibration data; act: the actual calibration data */
  439. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  440. #ifdef SW_CALIBRATION
  441. int mul;
  442. #else
  443. int err;
  444. #endif
  445. #ifdef SW_CALIBRATION
  446. mul = 0; /* only SW Calibration, disable HW Calibration */
  447. #else
  448. err = MPU6050_ReadOffset(client, obj->offset);
  449. if (err) {
  450. GSE_ERR("read offset fail, %d\n", err);
  451. return err;
  452. }
  453. mul = obj->reso->sensitivity / mpu6050_offset_resolution.sensitivity;
  454. #endif
  455. raw[MPU6050_AXIS_X] = obj->offset[MPU6050_AXIS_X]*mul + obj->cali_sw[MPU6050_AXIS_X];
  456. raw[MPU6050_AXIS_Y] = obj->offset[MPU6050_AXIS_Y]*mul + obj->cali_sw[MPU6050_AXIS_Y];
  457. raw[MPU6050_AXIS_Z] = obj->offset[MPU6050_AXIS_Z]*mul + obj->cali_sw[MPU6050_AXIS_Z];
  458. act[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X] * raw[MPU6050_AXIS_X];
  459. act[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y] * raw[MPU6050_AXIS_Y];
  460. act[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z] * raw[MPU6050_AXIS_Z];
  461. return 0;
  462. }
  463. /*----------------------------------------------------------------------------*/
  464. static int MPU6050_WriteCalibration(struct i2c_client *client, int dat[MPU6050_AXES_NUM])
  465. {
  466. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  467. int err;
  468. int cali[MPU6050_AXES_NUM], raw[MPU6050_AXES_NUM];
  469. #ifndef SW_CALIBRATION
  470. int lsb = mpu6050_offset_resolution.sensitivity;
  471. int divisor = obj->reso->sensitivity / lsb;
  472. #endif
  473. err = MPU6050_ReadCalibrationEx(client, cali, raw);
  474. if (err) { /*offset will be updated in obj->offset */
  475. GSE_ERR("read offset fail, %d\n", err);
  476. return err;
  477. }
  478. GSE_LOG("OLDOFF: (%+3d %+3d %+3d): (%+3d %+3d %+3d) / (%+3d %+3d %+3d)\n",
  479. raw[MPU6050_AXIS_X], raw[MPU6050_AXIS_Y], raw[MPU6050_AXIS_Z],
  480. obj->offset[MPU6050_AXIS_X], obj->offset[MPU6050_AXIS_Y], obj->offset[MPU6050_AXIS_Z],
  481. obj->cali_sw[MPU6050_AXIS_X], obj->cali_sw[MPU6050_AXIS_Y], obj->cali_sw[MPU6050_AXIS_Z]);
  482. /*calculate the real offset expected by caller */
  483. cali[MPU6050_AXIS_X] += dat[MPU6050_AXIS_X];
  484. cali[MPU6050_AXIS_Y] += dat[MPU6050_AXIS_Y];
  485. cali[MPU6050_AXIS_Z] += dat[MPU6050_AXIS_Z];
  486. GSE_LOG("UPDATE: (%+3d %+3d %+3d)\n",
  487. dat[MPU6050_AXIS_X], dat[MPU6050_AXIS_Y], dat[MPU6050_AXIS_Z]);
  488. #ifdef SW_CALIBRATION
  489. obj->cali_sw[MPU6050_AXIS_X] = obj->cvt.sign[MPU6050_AXIS_X]*(cali[obj->cvt.map[MPU6050_AXIS_X]]);
  490. obj->cali_sw[MPU6050_AXIS_Y] = obj->cvt.sign[MPU6050_AXIS_Y]*(cali[obj->cvt.map[MPU6050_AXIS_Y]]);
  491. obj->cali_sw[MPU6050_AXIS_Z] = obj->cvt.sign[MPU6050_AXIS_Z]*(cali[obj->cvt.map[MPU6050_AXIS_Z]]);
  492. #else
  493. obj->offset[MPU6050_AXIS_X] =
  494. (s8)(obj->cvt.sign[MPU6050_AXIS_X]*(cali[obj->cvt.map[MPU6050_AXIS_X]])/(divisor));
  495. obj->offset[MPU6050_AXIS_Y] =
  496. (s8)(obj->cvt.sign[MPU6050_AXIS_Y]*(cali[obj->cvt.map[MPU6050_AXIS_Y]])/(divisor));
  497. obj->offset[MPU6050_AXIS_Z] =
  498. (s8)(obj->cvt.sign[MPU6050_AXIS_Z]*(cali[obj->cvt.map[MPU6050_AXIS_Z]])/(divisor));
  499. /*convert software calibration using standard calibration*/
  500. obj->cali_sw[MPU6050_AXIS_X] = obj->cvt.sign[MPU6050_AXIS_X]*(cali[obj->cvt.map[MPU6050_AXIS_X]])%(divisor);
  501. obj->cali_sw[MPU6050_AXIS_Y] = obj->cvt.sign[MPU6050_AXIS_Y]*(cali[obj->cvt.map[MPU6050_AXIS_Y]])%(divisor);
  502. obj->cali_sw[MPU6050_AXIS_Z] = obj->cvt.sign[MPU6050_AXIS_Z]*(cali[obj->cvt.map[MPU6050_AXIS_Z]])%(divisor);
  503. GSE_LOG("NEWOFF: (%+3d %+3d %+3d): (%+3d %+3d %+3d) / (%+3d %+3d %+3d)\n",
  504. obj->offset[MPU6050_AXIS_X]*divisor + obj->cali_sw[MPU6050_AXIS_X],
  505. obj->offset[MPU6050_AXIS_Y]*divisor + obj->cali_sw[MPU6050_AXIS_Y],
  506. obj->offset[MPU6050_AXIS_Z]*divisor + obj->cali_sw[MPU6050_AXIS_Z],
  507. obj->offset[MPU6050_AXIS_X], obj->offset[MPU6050_AXIS_Y], obj->offset[MPU6050_AXIS_Z],
  508. obj->cali_sw[MPU6050_AXIS_X], obj->cali_sw[MPU6050_AXIS_Y], obj->cali_sw[MPU6050_AXIS_Z]);
  509. err = hwmsen_write_block(obj->client, MPU6050_REG_OFSX, obj->offset, MPU6050_AXES_NUM);
  510. if (err) {
  511. GSE_ERR("write offset fail: %d\n", err);
  512. return err;
  513. }
  514. #endif
  515. return err;
  516. }
  517. /*----------------------------------------------------------------------------*/
  518. static int MPU6050_CheckDeviceID(struct i2c_client *client)
  519. {
  520. u8 databuf[10];
  521. int res = 0;
  522. memset(databuf, 0, sizeof(u8)*10);
  523. res = mpu_i2c_read_block(client, MPU6050_REG_DEVID, databuf, 0x1);
  524. if (res < 0)
  525. goto exit_MPU6050_CheckDeviceID;
  526. GSE_LOG("MPU6050_CheckDeviceID 0x%x\n", databuf[0]);
  527. exit_MPU6050_CheckDeviceID:
  528. if (res < 0)
  529. return MPU6050_ERR_I2C;
  530. return MPU6050_SUCCESS;
  531. }
  532. /*----------------------------------------------------------------------------*/
  533. static int MPU6050_SetDataFormat(struct i2c_client *client, u8 dataformat)
  534. {
  535. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  536. u8 databuf[2];
  537. int res = 0;
  538. memset(databuf, 0, sizeof(u8)*2);
  539. res = mpu_i2c_read_block(client, MPU6050_REG_DATA_FORMAT, databuf, 0x1);
  540. if (res < 0)
  541. return MPU6050_ERR_I2C;
  542. /* write */
  543. databuf[0] = databuf[0] | dataformat;
  544. res = mpu_i2c_write_block(client, MPU6050_REG_DATA_FORMAT, databuf, 0x1);
  545. if (res < 0)
  546. return MPU6050_ERR_I2C;
  547. return MPU6050_SetDataResolution(obj);
  548. }
  549. /*----------------------------------------------------------------------------*/
  550. static int MPU6050_SetBWRate(struct i2c_client *client, u8 bwrate)
  551. {
  552. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  553. u8 databuf[10];
  554. int res = 0;
  555. if ((obj->bandwidth != bwrate) || (atomic_read(&obj->suspend))) {
  556. memset(databuf, 0, sizeof(u8)*10);
  557. /* read */
  558. res = mpu_i2c_read_block(client, MPU6050_REG_BW_RATE, databuf, 0x1);
  559. if (res < 0)
  560. return MPU6050_ERR_I2C;
  561. /* write */
  562. databuf[0] = databuf[0] | bwrate;
  563. res = mpu_i2c_write_block(client, MPU6050_REG_BW_RATE, databuf, 0x1);
  564. if (res < 0)
  565. return MPU6050_ERR_I2C;
  566. obj->bandwidth = bwrate;
  567. }
  568. return MPU6050_SUCCESS;
  569. }
  570. /*----------------------------------------------------------------------------*/
  571. static int MPU6050_Dev_Reset(struct i2c_client *client)
  572. {
  573. u8 databuf[10];
  574. int res = 0;
  575. memset(databuf, 0, sizeof(u8) * 10);
  576. /* read */
  577. res = mpu_i2c_read_block(client, MPU6050_REG_POWER_CTL, databuf, 0x1);
  578. if (res < 0)
  579. return MPU6050_ERR_I2C;
  580. /* write */
  581. databuf[0] = databuf[0] | MPU6050_DEV_RESET;
  582. res = mpu_i2c_write_block(client, MPU6050_REG_POWER_CTL, databuf, 0x1);
  583. if (res < 0)
  584. return MPU6050_ERR_I2C;
  585. do {
  586. res = mpu_i2c_read_block(client, MPU6050_REG_POWER_CTL, databuf, 0x1);
  587. if (res < 0)
  588. return MPU6050_ERR_I2C;
  589. GSE_LOG("[Gsensor] check reset bit");
  590. } while ((databuf[0]&MPU6050_DEV_RESET) != 0);
  591. msleep(50);
  592. return MPU6050_SUCCESS;
  593. }
  594. /*----------------------------------------------------------------------------*/
  595. static int MPU6050_Reset(struct i2c_client *client)
  596. {
  597. u8 databuf[10];
  598. int res = 0;
  599. /* write */
  600. databuf[0] = 0x7; /* reset gyro, g-sensor, temperature */
  601. res = mpu_i2c_write_block(client, MPU6050_REG_RESET, databuf, 0x1);
  602. if (res < 0)
  603. return MPU6050_ERR_I2C;
  604. msleep(20);
  605. return MPU6050_SUCCESS;
  606. }
  607. /*----------------------------------------------------------------------------*/
  608. static int MPU6050_SetIntEnable(struct i2c_client *client, u8 intenable)
  609. {
  610. u8 databuf[2];
  611. int res = 0;
  612. memset(databuf, 0, sizeof(u8)*2);
  613. databuf[0] = intenable;
  614. res = mpu_i2c_write_block(client, MPU6050_REG_INT_ENABLE, databuf, 0x1);
  615. if (res < 0)
  616. return MPU6050_ERR_I2C;
  617. return MPU6050_SUCCESS;
  618. }
  619. /*----------------------------------------------------------------------------*/
  620. static int mpu6050_gpio_config(void)
  621. {
  622. return 0;
  623. }
  624. static int mpu6050_init_client(struct i2c_client *client, int reset_cali)
  625. {
  626. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  627. int res = 0;
  628. mpu6050_gpio_config();
  629. res = MPU6050_SetPowerMode(client, true);
  630. if (res != MPU6050_SUCCESS) {
  631. GSE_ERR("set power error\n");
  632. return res;
  633. }
  634. res = MPU6050_CheckDeviceID(client);
  635. if (res != MPU6050_SUCCESS) {
  636. GSE_ERR("Check ID error\n");
  637. return res;
  638. }
  639. res = MPU6050_SetBWRate(client, MPU6050_BW_184HZ);
  640. if (res != MPU6050_SUCCESS) { /* 0x2C->BW=100Hz */
  641. GSE_ERR("set power error\n");
  642. return res;
  643. }
  644. res = MPU6050_SetDataFormat(client, MPU6050_RANGE_16G);
  645. if (res != MPU6050_SUCCESS) { /* 0x2C->BW=100Hz */
  646. GSE_ERR("set data format error\n");
  647. return res;
  648. }
  649. gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = obj->reso->sensitivity;
  650. res = MPU6050_SetIntEnable(client, 0x00); /* disable INT */
  651. if (res != MPU6050_SUCCESS) {
  652. GSE_ERR("mpu6050_SetIntEnable error\n");
  653. return res;
  654. }
  655. if (0 != reset_cali) {
  656. /*reset calibration only in power on */
  657. res = MPU6050_ResetCalibration(client);
  658. if (res != MPU6050_SUCCESS)
  659. return res;
  660. }
  661. #ifdef CONFIG_MPU6050_LOWPASS
  662. memset(&obj->fir, 0x00, sizeof(obj->fir));
  663. #endif
  664. return MPU6050_SUCCESS;
  665. }
  666. /*----------------------------------------------------------------------------*/
  667. static int MPU6050_ReadAllReg(struct i2c_client *client, char *buf, int bufsize)
  668. {
  669. u8 total_len = 0x5C; /* (0x75-0x19); */
  670. u8 addr = 0x19;
  671. u8 buff[total_len + 1];
  672. int err = 0;
  673. int i;
  674. if (sensor_power == false) {
  675. err = MPU6050_SetPowerMode(client, true);
  676. if (err)
  677. GSE_ERR("Power on mpu6050 error %d!\n", err);
  678. msleep(50);
  679. }
  680. mpu_i2c_read_block(client, addr, buff, total_len);
  681. for (i = 0; i <= total_len; i++)
  682. GSE_LOG("MPU6050 reg=0x%x, data=0x%x\n", (addr + i), buff[i]);
  683. return 0;
  684. }
  685. /*----------------------------------------------------------------------------*/
  686. static int MPU6050_ReadChipInfo(struct i2c_client *client, char *buf, int bufsize)
  687. {
  688. u8 databuf[10];
  689. memset(databuf, 0, sizeof(u8) * 10);
  690. if ((NULL == buf) || (bufsize <= 30))
  691. return -1;
  692. if (NULL == client) {
  693. *buf = 0;
  694. return -2;
  695. }
  696. sprintf(buf, "MPU6050 Chip");
  697. return 0;
  698. }
  699. /*----------------------------------------------------------------------------*/
  700. static int MPU6050_ReadSensorData(struct i2c_client *client, char *buf, int bufsize)
  701. {
  702. struct mpu6050_i2c_data *obj = obj_i2c_data; /* (struct mpu6050_i2c_data*)i2c_get_clientdata(client); */
  703. int acc[MPU6050_AXES_NUM];
  704. int res = 0;
  705. client = obj->client;
  706. if (atomic_read(&obj->suspend))
  707. return -3;
  708. if (NULL == buf)
  709. return -1;
  710. if (NULL == client) {
  711. *buf = 0;
  712. return -2;
  713. }
  714. if (sensor_power == false) {
  715. res = MPU6050_SetPowerMode(client, true);
  716. if (res)
  717. GSE_ERR("Power on mpu6050 error %d!\n", res);
  718. msleep(50);
  719. }
  720. res = MPU6050_ReadData(client, obj->data);
  721. if (res) {
  722. GSE_ERR("I2C error: ret value=%d", res);
  723. return -3;
  724. }
  725. obj->data[MPU6050_AXIS_X] += obj->cali_sw[MPU6050_AXIS_X];
  726. obj->data[MPU6050_AXIS_Y] += obj->cali_sw[MPU6050_AXIS_Y];
  727. obj->data[MPU6050_AXIS_Z] += obj->cali_sw[MPU6050_AXIS_Z];
  728. /*remap coordinate*/
  729. acc[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X]*obj->data[MPU6050_AXIS_X];
  730. acc[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y]*obj->data[MPU6050_AXIS_Y];
  731. acc[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z]*obj->data[MPU6050_AXIS_Z];
  732. /* Out put the mg */
  733. acc[MPU6050_AXIS_X] = acc[MPU6050_AXIS_X] * GRAVITY_EARTH_1000 / obj->reso->sensitivity;
  734. acc[MPU6050_AXIS_Y] = acc[MPU6050_AXIS_Y] * GRAVITY_EARTH_1000 / obj->reso->sensitivity;
  735. acc[MPU6050_AXIS_Z] = acc[MPU6050_AXIS_Z] * GRAVITY_EARTH_1000 / obj->reso->sensitivity;
  736. sprintf(buf, "%04x %04x %04x", acc[MPU6050_AXIS_X], acc[MPU6050_AXIS_Y], acc[MPU6050_AXIS_Z]);
  737. if (atomic_read(&obj->trace) & MPU6050_TRC_IOCTL)
  738. GSE_LOG("gsensor data: %s!\n", buf);
  739. return 0;
  740. }
  741. /*----------------------------------------------------------------------------*/
  742. static int MPU6050_ReadRawData(struct i2c_client *client, char *buf)
  743. {
  744. struct mpu6050_i2c_data *obj = (struct mpu6050_i2c_data *)i2c_get_clientdata(client);
  745. int res = 0;
  746. if (!buf || !client)
  747. return -EINVAL;
  748. if (atomic_read(&obj->suspend))
  749. return -EIO;
  750. res = MPU6050_ReadData(client, obj->data);
  751. if (res) {
  752. GSE_ERR("I2C error: ret value=%d", res);
  753. return -EIO;
  754. }
  755. sprintf(buf, "%04x %04x %04x", obj->data[MPU6050_AXIS_X],
  756. obj->data[MPU6050_AXIS_Y], obj->data[MPU6050_AXIS_Z]);
  757. return 0;
  758. }
  759. /*----------------------------------------------------------------------------*/
  760. static int MPU6050_InitSelfTest(struct i2c_client *client)
  761. {
  762. int res = 0;
  763. u8 data;
  764. res = MPU6050_SetBWRate(client, MPU6050_BW_184HZ);
  765. if (res != MPU6050_SUCCESS) { /* 0x2C->BW=100Hz */
  766. return res;
  767. }
  768. res = mpu_i2c_read_block(client, MPU6050_REG_DATA_FORMAT, &data, 1);
  769. if (res != MPU6050_SUCCESS)
  770. return res;
  771. return MPU6050_SUCCESS;
  772. }
  773. /*----------------------------------------------------------------------------*/
  774. static int MPU6050_JudgeTestResult(struct i2c_client *client, s32 prv[MPU6050_AXES_NUM], s32 nxt[MPU6050_AXES_NUM])
  775. {
  776. struct criteria {
  777. int min;
  778. int max;
  779. };
  780. struct criteria self[4][3] = {
  781. {{0, 540}, {0, 540}, {0, 875} },
  782. {{0, 270}, {0, 270}, {0, 438} },
  783. {{0, 135}, {0, 135}, {0, 219} },
  784. {{0, 67}, {0, 67}, {0, 110} },
  785. };
  786. struct criteria (*ptr)[3] = NULL;
  787. u8 format;
  788. int res;
  789. res = mpu_i2c_read_block(client, MPU6050_REG_DATA_FORMAT, &format, 1);
  790. if (res)
  791. return res;
  792. format = format & MPU6050_RANGE_16G;
  793. switch (format) {
  794. case MPU6050_RANGE_2G:
  795. /*GSE_LOG("format use self[0]\n");*/
  796. ptr = &self[0];
  797. break;
  798. case MPU6050_RANGE_4G:
  799. /*GSE_LOG("format use self[1]\n");*/
  800. ptr = &self[1];
  801. break;
  802. case MPU6050_RANGE_8G:
  803. /*GSE_LOG("format use self[2]\n");*/
  804. ptr = &self[2];
  805. break;
  806. case MPU6050_RANGE_16G:
  807. /*GSE_LOG("format use self[3]\n");*/
  808. ptr = &self[3];
  809. break;
  810. default:
  811. GSE_LOG("format unknown use\n");
  812. break;
  813. }
  814. if (!ptr) {
  815. GSE_ERR("null pointer\n");
  816. return -EINVAL;
  817. }
  818. GSE_LOG("format=0x%x\n", format);
  819. GSE_LOG("X diff is %ld\n", abs(nxt[MPU6050_AXIS_X] - prv[MPU6050_AXIS_X]));
  820. GSE_LOG("Y diff is %ld\n", abs(nxt[MPU6050_AXIS_Y] - prv[MPU6050_AXIS_Y]));
  821. GSE_LOG("Z diff is %ld\n", abs(nxt[MPU6050_AXIS_Z] - prv[MPU6050_AXIS_Z]));
  822. if ((abs(nxt[MPU6050_AXIS_X] - prv[MPU6050_AXIS_X]) > (*ptr)[MPU6050_AXIS_X].max) ||
  823. (abs(nxt[MPU6050_AXIS_X] - prv[MPU6050_AXIS_X]) < (*ptr)[MPU6050_AXIS_X].min)) {
  824. GSE_ERR("X is over range\n");
  825. res = -EINVAL;
  826. }
  827. if ((abs(nxt[MPU6050_AXIS_Y] - prv[MPU6050_AXIS_Y]) > (*ptr)[MPU6050_AXIS_Y].max) ||
  828. (abs(nxt[MPU6050_AXIS_Y] - prv[MPU6050_AXIS_Y]) < (*ptr)[MPU6050_AXIS_Y].min)) {
  829. GSE_ERR("Y is over range\n");
  830. res = -EINVAL;
  831. }
  832. if ((abs(nxt[MPU6050_AXIS_Z] - prv[MPU6050_AXIS_Z]) > (*ptr)[MPU6050_AXIS_Z].max) ||
  833. (abs(nxt[MPU6050_AXIS_Z] - prv[MPU6050_AXIS_Z]) < (*ptr)[MPU6050_AXIS_Z].min)) {
  834. GSE_ERR("Z is over range\n");
  835. res = -EINVAL;
  836. }
  837. return res;
  838. }
  839. /*----------------------------------------------------------------------------*/
  840. static ssize_t show_chipinfo_value(struct device_driver *ddri, char *buf)
  841. {
  842. struct i2c_client *client = mpu6050_i2c_client;
  843. char strbuf[MPU6050_BUFSIZE];
  844. if (NULL == client) {
  845. GSE_ERR("i2c client is null!!\n");
  846. return 0;
  847. }
  848. if (sensor_power == false)
  849. MPU6050_SetPowerMode(client, true);
  850. msleep(50);
  851. MPU6050_ReadAllReg(client, strbuf, MPU6050_BUFSIZE);
  852. MPU6050_ReadChipInfo(client, strbuf, MPU6050_BUFSIZE);
  853. return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
  854. }
  855. /*----------------------------------------------------------------------------*/
  856. static ssize_t show_sensordata_value(struct device_driver *ddri, char *buf)
  857. {
  858. struct i2c_client *client = mpu6050_i2c_client;
  859. char strbuf[MPU6050_BUFSIZE];
  860. if (NULL == client) {
  861. GSE_ERR("i2c client is null!!\n");
  862. return 0;
  863. }
  864. MPU6050_ReadSensorData(client, strbuf, MPU6050_BUFSIZE);
  865. return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
  866. }
  867. /*----------------------------------------------------------------------------*/
  868. static ssize_t show_cali_value(struct device_driver *ddri, char *buf)
  869. {
  870. struct i2c_client *client = mpu6050_i2c_client;
  871. struct mpu6050_i2c_data *obj;
  872. int err, len = 0, mul;
  873. int tmp[MPU6050_AXES_NUM];
  874. if (NULL == client) {
  875. GSE_ERR("i2c client is null!!\n");
  876. return 0;
  877. }
  878. obj = i2c_get_clientdata(client);
  879. err = MPU6050_ReadOffset(client, obj->offset);
  880. if (err)
  881. return -EINVAL;
  882. err = MPU6050_ReadCalibration(client, tmp);
  883. if (err)
  884. return -EINVAL;
  885. mul = obj->reso->sensitivity/mpu6050_offset_resolution.sensitivity;
  886. len += snprintf(buf+len, PAGE_SIZE-len, "[HW ][%d] (%+3d, %+3d, %+3d) : (0x%02X, 0x%02X, 0x%02X)\n", mul,
  887. obj->offset[MPU6050_AXIS_X], obj->offset[MPU6050_AXIS_Y], obj->offset[MPU6050_AXIS_Z],
  888. obj->offset[MPU6050_AXIS_X], obj->offset[MPU6050_AXIS_Y], obj->offset[MPU6050_AXIS_Z]);
  889. len += snprintf(buf+len, PAGE_SIZE-len, "[SW ][%d] (%+3d, %+3d, %+3d)\n", 1,
  890. obj->cali_sw[MPU6050_AXIS_X], obj->cali_sw[MPU6050_AXIS_Y], obj->cali_sw[MPU6050_AXIS_Z]);
  891. len += snprintf(buf+len, PAGE_SIZE-len, "[ALL] (%+3d, %+3d, %+3d) : (%+3d, %+3d, %+3d)\n",
  892. obj->offset[MPU6050_AXIS_X] * mul + obj->cali_sw[MPU6050_AXIS_X],
  893. obj->offset[MPU6050_AXIS_Y] * mul + obj->cali_sw[MPU6050_AXIS_Y],
  894. obj->offset[MPU6050_AXIS_Z] * mul + obj->cali_sw[MPU6050_AXIS_Z],
  895. tmp[MPU6050_AXIS_X], tmp[MPU6050_AXIS_Y], tmp[MPU6050_AXIS_Z]);
  896. return len;
  897. }
  898. /*----------------------------------------------------------------------------*/
  899. static ssize_t store_cali_value(struct device_driver *ddri, const char *buf, size_t count)
  900. {
  901. struct i2c_client *client = mpu6050_i2c_client;
  902. int err, x, y, z;
  903. int dat[MPU6050_AXES_NUM];
  904. if (!strncmp(buf, "rst", 3)) {
  905. err = MPU6050_ResetCalibration(client);
  906. if (err)
  907. GSE_ERR("reset offset err = %d\n", err);
  908. } else if (3 == sscanf(buf, "0x%02X 0x%02X 0x%02X", &x, &y, &z)) {
  909. dat[MPU6050_AXIS_X] = x;
  910. dat[MPU6050_AXIS_Y] = y;
  911. dat[MPU6050_AXIS_Z] = z;
  912. err = MPU6050_WriteCalibration(client, dat);
  913. if (err)
  914. GSE_ERR("write calibration err = %d\n", err);
  915. } else {
  916. GSE_ERR("invalid format\n");
  917. }
  918. return count;
  919. }
  920. /*----------------------------------------------------------------------------*/
  921. static ssize_t show_self_value(struct device_driver *ddri, char *buf)
  922. {
  923. struct i2c_client *client = mpu6050_i2c_client;
  924. if (NULL == client) {
  925. GSE_ERR("i2c client is null!!\n");
  926. return 0;
  927. }
  928. return snprintf(buf, 8, "%s\n", selftestRes);
  929. }
  930. /*----------------------------------------------------------------------------*/
  931. static ssize_t store_self_value(struct device_driver *ddri, const char *buf, size_t count)
  932. { /*write anything to this register will trigger the process */
  933. struct item {
  934. s16 raw[MPU6050_AXES_NUM];
  935. };
  936. struct i2c_client *client = mpu6050_i2c_client;
  937. int idx, res, num;
  938. long prv_len, nxt_len;
  939. struct item *prv = NULL, *nxt = NULL;
  940. s32 avg_prv[MPU6050_AXES_NUM] = { 0, 0, 0 };
  941. s32 avg_nxt[MPU6050_AXES_NUM] = { 0, 0, 0 };
  942. res = kstrtoint(buf, 10, &num);
  943. if (res != 0) {
  944. GSE_ERR("parse number fail\n");
  945. return count;
  946. } else if (num == 0) {
  947. GSE_ERR("invalid data count\n");
  948. return count;
  949. }
  950. prv_len = sizeof(*prv) * num;
  951. nxt_len = sizeof(*nxt) * num;
  952. prv = kzalloc(prv_len, GFP_KERNEL);
  953. nxt = kzalloc(prv_len, GFP_KERNEL);
  954. if (!prv || !nxt)
  955. goto exit;
  956. /*GSE_LOG("NORMAL:\n");*/
  957. MPU6050_SetPowerMode(client, true);
  958. msleep(50);
  959. for (idx = 0; idx < num; idx++) {
  960. res = MPU6050_ReadData(client, prv[idx].raw);
  961. if (res) {
  962. GSE_ERR("read data fail: %d\n", res);
  963. goto exit;
  964. }
  965. avg_prv[MPU6050_AXIS_X] += prv[idx].raw[MPU6050_AXIS_X];
  966. avg_prv[MPU6050_AXIS_Y] += prv[idx].raw[MPU6050_AXIS_Y];
  967. avg_prv[MPU6050_AXIS_Z] += prv[idx].raw[MPU6050_AXIS_Z];
  968. GSE_LOG("Normal:[%5d %5d %5d]\n", prv[idx].raw[MPU6050_AXIS_X],
  969. prv[idx].raw[MPU6050_AXIS_Y], prv[idx].raw[MPU6050_AXIS_Z]);
  970. }
  971. avg_prv[MPU6050_AXIS_X] /= num;
  972. avg_prv[MPU6050_AXIS_Y] /= num;
  973. avg_prv[MPU6050_AXIS_Z] /= num;
  974. /*initial setting for self test */
  975. /*GSE_LOG("SELFTEST:\n");*/
  976. for (idx = 0; idx < num; idx++) {
  977. res = MPU6050_ReadData(client, nxt[idx].raw);
  978. if (res) {
  979. GSE_ERR("read data fail: %d\n", res);
  980. goto exit;
  981. }
  982. avg_nxt[MPU6050_AXIS_X] += nxt[idx].raw[MPU6050_AXIS_X];
  983. avg_nxt[MPU6050_AXIS_Y] += nxt[idx].raw[MPU6050_AXIS_Y];
  984. avg_nxt[MPU6050_AXIS_Z] += nxt[idx].raw[MPU6050_AXIS_Z];
  985. GSE_LOG("SELFTESt: [%5d %5d %5d]\n", nxt[idx].raw[MPU6050_AXIS_X],
  986. nxt[idx].raw[MPU6050_AXIS_Y], nxt[idx].raw[MPU6050_AXIS_Z]);
  987. }
  988. avg_nxt[MPU6050_AXIS_X] /= num;
  989. avg_nxt[MPU6050_AXIS_Y] /= num;
  990. avg_nxt[MPU6050_AXIS_Z] /= num;
  991. GSE_LOG("X: %5d - %5d = %5d\n", avg_nxt[MPU6050_AXIS_X], avg_prv[MPU6050_AXIS_X],
  992. avg_nxt[MPU6050_AXIS_X] - avg_prv[MPU6050_AXIS_X]);
  993. GSE_LOG("Y: %5d - %5d = %5d\n", avg_nxt[MPU6050_AXIS_Y], avg_prv[MPU6050_AXIS_Y],
  994. avg_nxt[MPU6050_AXIS_Y] - avg_prv[MPU6050_AXIS_Y]);
  995. GSE_LOG("Z: %5d - %5d = %5d\n", avg_nxt[MPU6050_AXIS_Z], avg_prv[MPU6050_AXIS_Z],
  996. avg_nxt[MPU6050_AXIS_Z] - avg_prv[MPU6050_AXIS_Z]);
  997. if (!MPU6050_JudgeTestResult(client, avg_prv, avg_nxt)) {
  998. GSE_LOG("SELFTEST : PASS\n");
  999. strcpy(selftestRes, "y");
  1000. } else {
  1001. GSE_ERR("SELFTEST : FAIL\n");
  1002. strcpy(selftestRes, "n");
  1003. }
  1004. exit:
  1005. /*restore the setting */
  1006. mpu6050_init_client(client, 0);
  1007. kfree(prv);
  1008. kfree(nxt);
  1009. return count;
  1010. }
  1011. /*----------------------------------------------------------------------------*/
  1012. static ssize_t show_selftest_value(struct device_driver *ddri, char *buf)
  1013. {
  1014. struct i2c_client *client = mpu6050_i2c_client;
  1015. struct mpu6050_i2c_data *obj;
  1016. if (NULL == client) {
  1017. GSE_ERR("i2c client is null!!\n");
  1018. return 0;
  1019. }
  1020. obj = i2c_get_clientdata(client);
  1021. return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&obj->selftest));
  1022. }
  1023. /*----------------------------------------------------------------------------*/
  1024. static ssize_t store_selftest_value(struct device_driver *ddri, const char *buf, size_t count)
  1025. {
  1026. struct mpu6050_i2c_data *obj = obj_i2c_data;
  1027. int tmp;
  1028. if (NULL == obj) {
  1029. GSE_ERR("i2c data obj is null!!\n");
  1030. return 0;
  1031. }
  1032. if (0 == kstrtoint(buf, 10, &tmp)) {
  1033. if (atomic_read(&obj->selftest) && !tmp) {
  1034. /*enable -> disable */
  1035. mpu6050_init_client(obj->client, 0);
  1036. } else if (!atomic_read(&obj->selftest) && tmp) {
  1037. /*disable -> enable */
  1038. MPU6050_InitSelfTest(obj->client);
  1039. }
  1040. GSE_LOG("selftest: %d => %d\n", atomic_read(&obj->selftest), tmp);
  1041. atomic_set(&obj->selftest, tmp);
  1042. } else {
  1043. GSE_ERR("invalid content: '%s', length = %zu\n", buf, count);
  1044. }
  1045. return count;
  1046. }
  1047. /*----------------------------------------------------------------------------*/
  1048. static ssize_t show_firlen_value(struct device_driver *ddri, char *buf)
  1049. {
  1050. #ifdef CONFIG_MPU6050_LOWPASS
  1051. struct i2c_client *client = mpu6050_i2c_client;
  1052. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1053. if (atomic_read(&obj->firlen)) {
  1054. int idx, len = atomic_read(&obj->firlen);
  1055. GSE_LOG("len = %2d, idx = %2d\n", obj->fir.num, obj->fir.idx);
  1056. for (idx = 0; idx < len; idx++)
  1057. GSE_LOG("[%5d %5d %5d]\n", obj->fir.raw[idx][MPU6050_AXIS_X],
  1058. obj->fir.raw[idx][MPU6050_AXIS_Y], obj->fir.raw[idx][MPU6050_AXIS_Z]);
  1059. GSE_LOG("sum = [%5d %5d %5d]\n", obj->fir.sum[MPU6050_AXIS_X],
  1060. obj->fir.sum[MPU6050_AXIS_Y], obj->fir.sum[MPU6050_AXIS_Z]);
  1061. GSE_LOG("avg = [%5d %5d %5d]\n", obj->fir.sum[MPU6050_AXIS_X]/len,
  1062. obj->fir.sum[MPU6050_AXIS_Y]/len, obj->fir.sum[MPU6050_AXIS_Z]/len);
  1063. }
  1064. return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&obj->firlen));
  1065. #else
  1066. return snprintf(buf, PAGE_SIZE, "not support\n");
  1067. #endif
  1068. }
  1069. /*----------------------------------------------------------------------------*/
  1070. static ssize_t store_firlen_value(struct device_driver *ddri, const char *buf, size_t count)
  1071. {
  1072. #ifdef CONFIG_MPU6050_LOWPASS
  1073. struct i2c_client *client = mpu6050_i2c_client;
  1074. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1075. int firlen;
  1076. if (0 != kstrtoint(buf, 10, &firlen)) {
  1077. GSE_ERR("invallid format\n");
  1078. } else if (firlen > C_MAX_FIR_LENGTH) {
  1079. GSE_ERR("exceeds maximum filter length\n");
  1080. } else {
  1081. atomic_set(&obj->firlen, firlen);
  1082. if (0 == firlen) {
  1083. atomic_set(&obj->fir_en, 0);
  1084. } else {
  1085. memset(&obj->fir, 0x00, sizeof(obj->fir));
  1086. atomic_set(&obj->fir_en, 1);
  1087. }
  1088. }
  1089. #endif
  1090. return count;
  1091. }
  1092. /*----------------------------------------------------------------------------*/
  1093. static ssize_t show_trace_value(struct device_driver *ddri, char *buf)
  1094. {
  1095. ssize_t res;
  1096. struct mpu6050_i2c_data *obj = obj_i2c_data;
  1097. if (obj == NULL) {
  1098. GSE_ERR("i2c_data obj is null!!\n");
  1099. return 0;
  1100. }
  1101. res = snprintf(buf, PAGE_SIZE, "0x%04X\n", atomic_read(&obj->trace));
  1102. return res;
  1103. }
  1104. /*----------------------------------------------------------------------------*/
  1105. static ssize_t store_trace_value(struct device_driver *ddri, const char *buf, size_t count)
  1106. {
  1107. struct mpu6050_i2c_data *obj = obj_i2c_data;
  1108. int trace;
  1109. if (obj == NULL) {
  1110. GSE_ERR("i2c_data obj is null!!\n");
  1111. return 0;
  1112. }
  1113. if (0 == kstrtoint(buf, 16, &trace))
  1114. atomic_set(&obj->trace, trace);
  1115. else
  1116. GSE_ERR("invalid content: '%s', length = %zu\n", buf, count);
  1117. return count;
  1118. }
  1119. /*----------------------------------------------------------------------------*/
  1120. static ssize_t show_status_value(struct device_driver *ddri, char *buf)
  1121. {
  1122. ssize_t len = 0;
  1123. struct mpu6050_i2c_data *obj = obj_i2c_data;
  1124. if (obj == NULL) {
  1125. GSE_ERR("i2c_data obj is null!!\n");
  1126. return 0;
  1127. }
  1128. if (obj->hw)
  1129. len += snprintf(buf+len, PAGE_SIZE-len, "CUST: %d %d (%d %d)\n",
  1130. obj->hw->i2c_num, obj->hw->direction, obj->hw->power_id, obj->hw->power_vol);
  1131. else
  1132. len += snprintf(buf + len, PAGE_SIZE - len, "CUST: NULL\n");
  1133. return len;
  1134. }
  1135. /*----------------------------------------------------------------------------*/
  1136. static DRIVER_ATTR(chipinfo, S_IRUGO, show_chipinfo_value, NULL);
  1137. static DRIVER_ATTR(sensordata, S_IRUGO, show_sensordata_value, NULL);
  1138. static DRIVER_ATTR(cali, S_IWUSR | S_IRUGO, show_cali_value, store_cali_value);
  1139. static DRIVER_ATTR(self, S_IWUSR | S_IRUGO, show_selftest_value, store_selftest_value);
  1140. static DRIVER_ATTR(selftest, S_IWUSR | S_IRUGO, show_self_value, store_self_value);
  1141. static DRIVER_ATTR(firlen, S_IWUSR | S_IRUGO, show_firlen_value, store_firlen_value);
  1142. static DRIVER_ATTR(trace, S_IWUSR | S_IRUGO, show_trace_value, store_trace_value);
  1143. static DRIVER_ATTR(status, S_IRUGO, show_status_value, NULL);
  1144. /*----------------------------------------------------------------------------*/
  1145. static struct driver_attribute *mpu6050_attr_list[] = {
  1146. &driver_attr_chipinfo, /*chip information */
  1147. &driver_attr_sensordata, /*dump sensor data */
  1148. &driver_attr_cali, /*show calibration data */
  1149. &driver_attr_self, /*self test demo */
  1150. &driver_attr_selftest, /*self control: 0: disable, 1: enable */
  1151. &driver_attr_firlen, /*filter length: 0: disable, others: enable */
  1152. &driver_attr_trace, /*trace log */
  1153. &driver_attr_status,
  1154. };
  1155. /*----------------------------------------------------------------------------*/
  1156. static int mpu6050_create_attr(struct device_driver *driver)
  1157. {
  1158. int idx, err = 0;
  1159. int num = (int)(sizeof(mpu6050_attr_list) / sizeof(mpu6050_attr_list[0]));
  1160. if (driver == NULL)
  1161. return -EINVAL;
  1162. for (idx = 0; idx < num; idx++) {
  1163. err = driver_create_file(driver, mpu6050_attr_list[idx]);
  1164. if (0 != err) {
  1165. GSE_ERR("driver_create_file (%s) = %d\n", mpu6050_attr_list[idx]->attr.name,
  1166. err);
  1167. break;
  1168. }
  1169. }
  1170. return err;
  1171. }
  1172. /*----------------------------------------------------------------------------*/
  1173. static int mpu6050_delete_attr(struct device_driver *driver)
  1174. {
  1175. int idx, err = 0;
  1176. int num = (int)(sizeof(mpu6050_attr_list) / sizeof(mpu6050_attr_list[0]));
  1177. if (driver == NULL)
  1178. return -EINVAL;
  1179. for (idx = 0; idx < num; idx++)
  1180. driver_remove_file(driver, mpu6050_attr_list[idx]);
  1181. return err;
  1182. }
  1183. /*----------------------------------------------------------------------------*/
  1184. int gsensor_operate(void *self, uint32_t command, void *buff_in, int size_in,
  1185. void *buff_out, int size_out, int *actualout)
  1186. {
  1187. int err = 0;
  1188. int value, sample_delay;
  1189. struct mpu6050_i2c_data *priv = (struct mpu6050_i2c_data *)self;
  1190. struct hwm_sensor_data *gsensor_data;
  1191. char buff[MPU6050_BUFSIZE];
  1192. switch (command) {
  1193. case SENSOR_DELAY:
  1194. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1195. GSE_ERR("Set delay parameter error!\n");
  1196. err = -EINVAL;
  1197. } else {
  1198. value = *(int *)buff_in;
  1199. if (value <= 5)
  1200. sample_delay = MPU6050_BW_184HZ;
  1201. else if (value <= 10)
  1202. sample_delay = MPU6050_BW_94HZ;
  1203. else
  1204. sample_delay = MPU6050_BW_44HZ;
  1205. GSE_LOG("Set delay parameter value:%d\n", value);
  1206. err = MPU6050_SetBWRate(priv->client, sample_delay);
  1207. if (err != MPU6050_SUCCESS) { /* 0x2C->BW=100Hz */
  1208. GSE_ERR("Set delay parameter error!\n");
  1209. }
  1210. if (value >= 50) {
  1211. atomic_set(&priv->filter, 0);
  1212. } else {
  1213. #if defined(CONFIG_MPU6050_LOWPASS)
  1214. priv->fir.num = 0;
  1215. priv->fir.idx = 0;
  1216. priv->fir.sum[MPU6050_AXIS_X] = 0;
  1217. priv->fir.sum[MPU6050_AXIS_Y] = 0;
  1218. priv->fir.sum[MPU6050_AXIS_Z] = 0;
  1219. #endif
  1220. atomic_set(&priv->filter, 1);
  1221. }
  1222. }
  1223. break;
  1224. case SENSOR_ENABLE:
  1225. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1226. GSE_ERR("Enable sensor parameter error!\n");
  1227. err = -EINVAL;
  1228. } else {
  1229. value = *(int *)buff_in;
  1230. if (((value == 0) && (sensor_power == false)) || ((value == 1) && (sensor_power == true)))
  1231. GSE_LOG("Gsensor device have updated!\n");
  1232. else
  1233. err = MPU6050_SetPowerMode(priv->client, !sensor_power);
  1234. }
  1235. break;
  1236. case SENSOR_GET_DATA:
  1237. if ((buff_out == NULL) || (size_out < sizeof(struct hwm_sensor_data))) {
  1238. GSE_ERR("get sensor data parameter error!\n");
  1239. err = -EINVAL;
  1240. } else {
  1241. gsensor_data = (struct hwm_sensor_data *) buff_out;
  1242. err = MPU6050_ReadSensorData(priv->client, buff, MPU6050_BUFSIZE);
  1243. if (!err) {
  1244. err = sscanf(buff, "%x %x %x", &gsensor_data->values[0],
  1245. &gsensor_data->values[1], &gsensor_data->values[2]);
  1246. if (3 == err) {
  1247. gsensor_data->status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1248. gsensor_data->value_divide = 1000;
  1249. } else
  1250. GSE_ERR("gsensor operate function sscanf invaild parameter !\n");
  1251. }
  1252. }
  1253. break;
  1254. default:
  1255. GSE_ERR("gsensor operate function no this parameter %d!\n", command);
  1256. err = -1;
  1257. break;
  1258. }
  1259. return err;
  1260. }
  1261. /******************************************************************************
  1262. * Function Configuration
  1263. ******************************************************************************/
  1264. static int mpu6050_open(struct inode *inode, struct file *file)
  1265. {
  1266. file->private_data = mpu6050_i2c_client;
  1267. if (file->private_data == NULL) {
  1268. GSE_ERR("null pointer!!\n");
  1269. return -EINVAL;
  1270. }
  1271. return nonseekable_open(inode, file);
  1272. }
  1273. /*----------------------------------------------------------------------------*/
  1274. static int mpu6050_release(struct inode *inode, struct file *file)
  1275. {
  1276. file->private_data = NULL;
  1277. return 0;
  1278. }
  1279. /*----------------------------------------------------------------------------*/
  1280. #ifdef CONFIG_COMPAT
  1281. static long mpu6050_compat_ioctl(struct file *file, unsigned int cmd,
  1282. unsigned long arg)
  1283. {
  1284. long err = 0;
  1285. void __user *arg32 = compat_ptr(arg);
  1286. if (!file->f_op || !file->f_op->unlocked_ioctl)
  1287. return -ENOTTY;
  1288. switch (cmd) {
  1289. case COMPAT_GSENSOR_IOCTL_READ_SENSORDATA:
  1290. if (arg32 == NULL) {
  1291. err = -EINVAL;
  1292. break;
  1293. }
  1294. err = file->f_op->unlocked_ioctl(file, GSENSOR_IOCTL_READ_SENSORDATA, (unsigned long)arg32);
  1295. if (err) {
  1296. GSE_ERR("GSENSOR_IOCTL_READ_SENSORDATA unlocked_ioctl failed.");
  1297. return err;
  1298. }
  1299. break;
  1300. case COMPAT_GSENSOR_IOCTL_SET_CALI:
  1301. if (arg32 == NULL) {
  1302. err = -EINVAL;
  1303. break;
  1304. }
  1305. err = file->f_op->unlocked_ioctl(file, GSENSOR_IOCTL_SET_CALI, (unsigned long)arg32);
  1306. if (err) {
  1307. GSE_ERR("GSENSOR_IOCTL_SET_CALI unlocked_ioctl failed.");
  1308. return err;
  1309. }
  1310. break;
  1311. case COMPAT_GSENSOR_IOCTL_GET_CALI:
  1312. if (arg32 == NULL) {
  1313. err = -EINVAL;
  1314. break;
  1315. }
  1316. err = file->f_op->unlocked_ioctl(file, GSENSOR_IOCTL_GET_CALI, (unsigned long)arg32);
  1317. if (err) {
  1318. GSE_ERR("GSENSOR_IOCTL_GET_CALI unlocked_ioctl failed.");
  1319. return err;
  1320. }
  1321. break;
  1322. case COMPAT_GSENSOR_IOCTL_CLR_CALI:
  1323. if (arg32 == NULL) {
  1324. err = -EINVAL;
  1325. break;
  1326. }
  1327. err = file->f_op->unlocked_ioctl(file, GSENSOR_IOCTL_CLR_CALI, (unsigned long)arg32);
  1328. if (err) {
  1329. GSE_ERR("GSENSOR_IOCTL_CLR_CALI unlocked_ioctl failed.");
  1330. return err;
  1331. }
  1332. break;
  1333. default:
  1334. GSE_ERR("unknown IOCTL: 0x%08x\n", cmd);
  1335. err = -ENOIOCTLCMD;
  1336. break;
  1337. }
  1338. return err;
  1339. }
  1340. #endif
  1341. static long mpu6050_unlocked_ioctl(struct file *file, unsigned int cmd,
  1342. unsigned long arg)
  1343. {
  1344. struct i2c_client *client = (struct i2c_client *)file->private_data;
  1345. struct mpu6050_i2c_data *obj = (struct mpu6050_i2c_data *)i2c_get_clientdata(client);
  1346. char strbuf[MPU6050_BUFSIZE];
  1347. void __user *data;
  1348. struct SENSOR_DATA sensor_data;
  1349. long err = 0;
  1350. int cali[3];
  1351. if (_IOC_DIR(cmd) & _IOC_READ)
  1352. err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
  1353. else if (_IOC_DIR(cmd) & _IOC_WRITE)
  1354. err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
  1355. if (err) {
  1356. GSE_ERR("access error: %08X, (%2d, %2d)\n", cmd, _IOC_DIR(cmd), _IOC_SIZE(cmd));
  1357. return -EFAULT;
  1358. }
  1359. switch (cmd) {
  1360. case GSENSOR_IOCTL_INIT:
  1361. mpu6050_init_client(client, 0);
  1362. break;
  1363. case GSENSOR_IOCTL_READ_CHIPINFO:
  1364. data = (void __user *)arg;
  1365. if (data == NULL) {
  1366. err = -EINVAL;
  1367. break;
  1368. }
  1369. MPU6050_ReadChipInfo(client, strbuf, MPU6050_BUFSIZE);
  1370. if (copy_to_user(data, strbuf, strlen(strbuf) + 1)) {
  1371. err = -EFAULT;
  1372. break;
  1373. }
  1374. break;
  1375. case GSENSOR_IOCTL_READ_SENSORDATA:
  1376. data = (void __user *)arg;
  1377. if (data == NULL) {
  1378. err = -EINVAL;
  1379. break;
  1380. }
  1381. MPU6050_ReadSensorData(client, strbuf, MPU6050_BUFSIZE);
  1382. if (copy_to_user(data, strbuf, strlen(strbuf) + 1)) {
  1383. err = -EFAULT;
  1384. break;
  1385. }
  1386. break;
  1387. case GSENSOR_IOCTL_READ_GAIN:
  1388. data = (void __user *)arg;
  1389. if (data == NULL) {
  1390. err = -EINVAL;
  1391. break;
  1392. }
  1393. if (copy_to_user(data, &gsensor_gain, sizeof(struct GSENSOR_VECTOR3D))) {
  1394. err = -EFAULT;
  1395. break;
  1396. }
  1397. break;
  1398. case GSENSOR_IOCTL_READ_RAW_DATA:
  1399. data = (void __user *)arg;
  1400. if (data == NULL) {
  1401. err = -EINVAL;
  1402. break;
  1403. }
  1404. if (atomic_read(&obj->suspend)) {
  1405. err = -EINVAL;
  1406. } else {
  1407. MPU6050_ReadRawData(client, strbuf);
  1408. if (copy_to_user(data, strbuf, strlen(strbuf) + 1)) {
  1409. err = -EFAULT;
  1410. break;
  1411. }
  1412. }
  1413. break;
  1414. case GSENSOR_IOCTL_SET_CALI:
  1415. data = (void __user *)arg;
  1416. if (data == NULL) {
  1417. err = -EINVAL;
  1418. break;
  1419. }
  1420. if (copy_from_user(&sensor_data, data, sizeof(sensor_data))) {
  1421. err = -EFAULT;
  1422. break;
  1423. }
  1424. if (atomic_read(&obj->suspend)) {
  1425. GSE_ERR("Perform calibration in suspend state!!\n");
  1426. err = -EINVAL;
  1427. } else {
  1428. cali[MPU6050_AXIS_X] = sensor_data.x * obj->reso->sensitivity / GRAVITY_EARTH_1000;
  1429. cali[MPU6050_AXIS_Y] = sensor_data.y * obj->reso->sensitivity / GRAVITY_EARTH_1000;
  1430. cali[MPU6050_AXIS_Z] = sensor_data.z * obj->reso->sensitivity / GRAVITY_EARTH_1000;
  1431. err = MPU6050_WriteCalibration(client, cali);
  1432. }
  1433. break;
  1434. case GSENSOR_IOCTL_CLR_CALI:
  1435. err = MPU6050_ResetCalibration(client);
  1436. break;
  1437. case GSENSOR_IOCTL_GET_CALI:
  1438. data = (void __user *)arg;
  1439. if (data == NULL) {
  1440. err = -EINVAL;
  1441. break;
  1442. }
  1443. err = MPU6050_ReadCalibration(client, cali);
  1444. if (err)
  1445. break;
  1446. sensor_data.x = cali[MPU6050_AXIS_X] * GRAVITY_EARTH_1000 / obj->reso->sensitivity;
  1447. sensor_data.y = cali[MPU6050_AXIS_Y] * GRAVITY_EARTH_1000 / obj->reso->sensitivity;
  1448. sensor_data.z = cali[MPU6050_AXIS_Z] * GRAVITY_EARTH_1000 / obj->reso->sensitivity;
  1449. if (copy_to_user(data, &sensor_data, sizeof(sensor_data))) {
  1450. err = -EFAULT;
  1451. break;
  1452. }
  1453. break;
  1454. default:
  1455. GSE_ERR("unknown IOCTL: 0x%08x\n", cmd);
  1456. err = -ENOIOCTLCMD;
  1457. break;
  1458. }
  1459. return err;
  1460. }
  1461. /*----------------------------------------------------------------------------*/
  1462. static const struct file_operations mpu6050_fops = {
  1463. .open = mpu6050_open,
  1464. .release = mpu6050_release,
  1465. .unlocked_ioctl = mpu6050_unlocked_ioctl,
  1466. #ifdef CONFIG_COMPAT
  1467. .compat_ioctl = mpu6050_compat_ioctl,
  1468. #endif
  1469. };
  1470. /*----------------------------------------------------------------------------*/
  1471. static struct miscdevice mpu6050_device = {
  1472. .minor = MISC_DYNAMIC_MINOR,
  1473. .name = "gsensor",
  1474. .fops = &mpu6050_fops,
  1475. };
  1476. /*----------------------------------------------------------------------------*/
  1477. #ifndef USE_EARLY_SUSPEND
  1478. /*----------------------------------------------------------------------------*/
  1479. static int mpu6050_suspend(struct i2c_client *client, pm_message_t msg)
  1480. {
  1481. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1482. int err = 0;
  1483. GSE_FUN();
  1484. if (msg.event == PM_EVENT_SUSPEND) {
  1485. if (obj == NULL) {
  1486. GSE_ERR("null pointer!!\n");
  1487. return -EINVAL;
  1488. }
  1489. atomic_set(&obj->suspend, 1);
  1490. err = MPU6050_SetPowerMode(obj->client, false);
  1491. if (err) {
  1492. GSE_ERR("write power control fail!!\n");
  1493. return err;
  1494. }
  1495. MPU6050_power(obj->hw, 0);
  1496. GSE_LOG("mpu6050_suspend ok\n");
  1497. }
  1498. return err;
  1499. }
  1500. /*----------------------------------------------------------------------------*/
  1501. static int mpu6050_resume(struct i2c_client *client)
  1502. {
  1503. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1504. int err;
  1505. GSE_FUN();
  1506. if (obj == NULL) {
  1507. GSE_ERR("null pointer!!\n");
  1508. return -EINVAL;
  1509. }
  1510. MPU6050_power(obj->hw, 1);
  1511. err = mpu6050_init_client(client, 0);
  1512. if (err) {
  1513. GSE_ERR("initialize client fail!!\n");
  1514. return err;
  1515. }
  1516. atomic_set(&obj->suspend, 0);
  1517. GSE_LOG("mpu6050_resume ok\n");
  1518. return 0;
  1519. }
  1520. /*----------------------------------------------------------------------------*/
  1521. #else /*CONFIG_HAS_EARLY_SUSPEND is defined */
  1522. /*----------------------------------------------------------------------------*/
  1523. static void mpu6050_early_suspend(struct early_suspend *h)
  1524. {
  1525. struct mpu6050_i2c_data *obj = container_of(h, struct mpu6050_i2c_data, early_drv);
  1526. int err;
  1527. GSE_FUN();
  1528. if (obj == NULL) {
  1529. GSE_ERR("null pointer!!\n");
  1530. return;
  1531. }
  1532. atomic_set(&obj->suspend, 1);
  1533. err = MPU6050_SetPowerMode(obj->client, false);
  1534. if (err) {
  1535. GSE_ERR("write power control fail!!\n");
  1536. return;
  1537. }
  1538. if (MPU6050_gyro_mode() == false) {
  1539. MPU6050_Dev_Reset(obj->client);
  1540. MPU6050_Reset(obj->client);
  1541. }
  1542. obj->bandwidth = 0;
  1543. sensor_power = false;
  1544. MPU6050_power(obj->hw, 0);
  1545. }
  1546. /*----------------------------------------------------------------------------*/
  1547. static void mpu6050_late_resume(struct early_suspend *h)
  1548. {
  1549. struct mpu6050_i2c_data *obj = container_of(h, struct mpu6050_i2c_data, early_drv);
  1550. int err;
  1551. GSE_FUN();
  1552. if (obj == NULL) {
  1553. GSE_ERR("null pointer!!\n");
  1554. return;
  1555. }
  1556. MPU6050_power(obj->hw, 1);
  1557. err = mpu6050_init_client(obj->client, 0);
  1558. if (err) {
  1559. GSE_ERR("initialize client fail!!\n");
  1560. return;
  1561. }
  1562. atomic_set(&obj->suspend, 0);
  1563. }
  1564. /*----------------------------------------------------------------------------*/
  1565. #endif /*CONFIG_HAS_EARLYSUSPEND */
  1566. /*----------------------------------------------------------------------------*/
  1567. static int mpu6050_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
  1568. {
  1569. strcpy(info->type, MPU6050_DEV_NAME);
  1570. return 0;
  1571. }
  1572. /* if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL*/
  1573. static int mpu6050_open_report_data(int open)
  1574. {
  1575. /*should queuq work to report event if is_report_input_direct=true*/
  1576. return 0;
  1577. }
  1578. /* if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL*/
  1579. static int mpu6050_enable_nodata(int en)
  1580. {
  1581. int res = 0;
  1582. int retry = 0;
  1583. bool power = false;
  1584. if (1 == en)
  1585. power = true;
  1586. if (0 == en)
  1587. power = false;
  1588. for (retry = 0; retry < 3; retry++) {
  1589. res = MPU6050_SetPowerMode(obj_i2c_data->client, power);
  1590. if (res == 0)
  1591. break;
  1592. }
  1593. if (res != MPU6050_SUCCESS) {
  1594. GSE_ERR("MPU6050_SetPowerMode fail!\n");
  1595. return -1;
  1596. }
  1597. GSE_LOG("mpu6050_enable_nodata OK!\n");
  1598. return 0;
  1599. }
  1600. static int mpu6050_set_delay(u64 ns)
  1601. {
  1602. int value = 0;
  1603. int sample_delay = 0;
  1604. int err;
  1605. value = (int)ns/1000/1000;
  1606. if (value <= 5)
  1607. sample_delay = MPU6050_BW_184HZ;
  1608. else if (value <= 10)
  1609. sample_delay = MPU6050_BW_94HZ;
  1610. else
  1611. sample_delay = MPU6050_BW_44HZ;
  1612. err = MPU6050_SetBWRate(obj_i2c_data->client, sample_delay);
  1613. if (err != MPU6050_SUCCESS) {
  1614. GSE_ERR("mpu6050_set_delay Set delay parameter error!\n");
  1615. return -1;
  1616. }
  1617. GSE_LOG("mpu6050_set_delay (%d)\n", value);
  1618. return 0;
  1619. }
  1620. static int mpu6050_get_data(int *x, int *y, int *z, int *status)
  1621. {
  1622. char buff[MPU6050_BUFSIZE];
  1623. int err;
  1624. MPU6050_ReadSensorData(obj_i2c_data->client, buff, MPU6050_BUFSIZE);
  1625. err = sscanf(buff, "%x %x %x", x, y, z);
  1626. if (err == 3)
  1627. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1628. else
  1629. GSE_ERR("gsensor operate function sscanf invaild parameter !\n");
  1630. return 0;
  1631. }
  1632. /*----------------------------------------------------------------------------*/
  1633. static int mpu6050_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  1634. {
  1635. struct i2c_client *new_client;
  1636. struct mpu6050_i2c_data *obj;
  1637. int err = 0;
  1638. struct acc_control_path ctl = {0};
  1639. struct acc_data_path data = {0};
  1640. GSE_FUN();
  1641. obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  1642. if (!(obj)) {
  1643. err = -ENOMEM;
  1644. goto exit;
  1645. }
  1646. memset(obj, 0, sizeof(struct mpu6050_i2c_data));
  1647. obj->hw = hw;
  1648. err = hwmsen_get_convert(obj->hw->direction, &obj->cvt);
  1649. if (err) {
  1650. GSE_ERR("invalid direction: %d\n", obj->hw->direction);
  1651. goto exit;
  1652. }
  1653. obj_i2c_data = obj;
  1654. obj->client = client;
  1655. /* obj->client->timing = 400; */
  1656. new_client = obj->client;
  1657. i2c_set_clientdata(new_client, obj);
  1658. atomic_set(&obj->trace, 0);
  1659. atomic_set(&obj->suspend, 0);
  1660. #ifdef CONFIG_MPU6050_LOWPASS
  1661. if (obj->hw->firlen > C_MAX_FIR_LENGTH)
  1662. atomic_set(&obj->firlen, C_MAX_FIR_LENGTH);
  1663. else
  1664. atomic_set(&obj->firlen, obj->hw->firlen);
  1665. if (atomic_read(&obj->firlen) > 0)
  1666. atomic_set(&obj->fir_en, 1);
  1667. #endif
  1668. mpu6050_i2c_client = new_client;
  1669. MPU6050_Dev_Reset(new_client);
  1670. MPU6050_Reset(new_client);
  1671. err = mpu6050_init_client(new_client, 1);
  1672. if (err)
  1673. goto exit_init_failed;
  1674. err = misc_register(&mpu6050_device);
  1675. if (err) {
  1676. GSE_ERR("mpu6050_device register failed\n");
  1677. goto exit_misc_device_register_failed;
  1678. }
  1679. ctl.is_use_common_factory = false;
  1680. err = mpu6050_create_attr(&(mpu6050_init_info.platform_diver_addr->driver));
  1681. if (err) {
  1682. GSE_ERR("create attribute err = %d\n", err);
  1683. goto exit_create_attr_failed;
  1684. }
  1685. ctl.open_report_data = mpu6050_open_report_data;
  1686. ctl.enable_nodata = mpu6050_enable_nodata;
  1687. ctl.set_delay = mpu6050_set_delay;
  1688. ctl.is_report_input_direct = false;
  1689. ctl.is_support_batch = obj->hw->is_batch_supported;
  1690. err = acc_register_control_path(&ctl);
  1691. if (err) {
  1692. GSE_ERR("register acc control path err\n");
  1693. goto exit_kfree;
  1694. }
  1695. data.get_data = mpu6050_get_data;
  1696. data.vender_div = 1000;
  1697. err = acc_register_data_path(&data);
  1698. if (err) {
  1699. GSE_ERR("register acc data path err= %d\n", err);
  1700. goto exit_kfree;
  1701. }
  1702. #ifdef USE_EARLY_SUSPEND
  1703. obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 2,
  1704. obj->early_drv.suspend = mpu6050_early_suspend,
  1705. obj->early_drv.resume = mpu6050_late_resume, register_early_suspend(&obj->early_drv);
  1706. #endif
  1707. mpu6050_init_flag = 0;
  1708. GSE_LOG("%s: OK\n", __func__);
  1709. return 0;
  1710. exit_create_attr_failed:
  1711. misc_deregister(&mpu6050_device);
  1712. exit_misc_device_register_failed:
  1713. exit_init_failed:
  1714. /* i2c_detach_client(new_client); */
  1715. exit_kfree:
  1716. kfree(obj);
  1717. exit:
  1718. GSE_ERR("%s: err = %d\n", __func__, err);
  1719. mpu6050_init_flag = -1;
  1720. return err;
  1721. }
  1722. /*----------------------------------------------------------------------------*/
  1723. static int mpu6050_i2c_remove(struct i2c_client *client)
  1724. {
  1725. int err = 0;
  1726. err = mpu6050_delete_attr(&(mpu6050_init_info.platform_diver_addr->driver));
  1727. if (err)
  1728. GSE_ERR("mpu6050_delete_attr fail: %d\n", err);
  1729. err = misc_deregister(&mpu6050_device);
  1730. if (err)
  1731. GSE_ERR("misc_deregister fail: %d\n", err);
  1732. err = hwmsen_detach(ID_ACCELEROMETER);
  1733. if (err)
  1734. GSE_ERR("hwmsen_detach fail: %d\n", err);
  1735. mpu6050_i2c_client = NULL;
  1736. i2c_unregister_device(client);
  1737. kfree(i2c_get_clientdata(client));
  1738. return 0;
  1739. }
  1740. /*----------------------------------------------------------------------------*/
  1741. /*----------------------------------------------------------------------------*/
  1742. static int mpu6050_remove(void)
  1743. {
  1744. /*GSE_FUN();*/
  1745. MPU6050_power(hw, 0);
  1746. i2c_del_driver(&mpu6050g_i2c_driver);
  1747. return 0;
  1748. }
  1749. /*----------------------------------------------------------------------------*/
  1750. static int mpu6050_local_init(void)
  1751. {
  1752. MPU6050_power(hw, 1);
  1753. if (i2c_add_driver(&mpu6050g_i2c_driver)) {
  1754. GSE_ERR("add driver error\n");
  1755. return -1;
  1756. }
  1757. if (-1 == mpu6050_init_flag)
  1758. return -1;
  1759. return 0;
  1760. }
  1761. /*----------------------------------------------------------------------------*/
  1762. static int __init mpu6050gse_init(void)
  1763. {
  1764. const char *name = "mediatek,mpu6050g";
  1765. hw = get_accel_dts_func(name, hw);
  1766. if (!hw)
  1767. GSE_ERR("get dts info fail\n");
  1768. acc_driver_add(&mpu6050_init_info);
  1769. return 0;
  1770. }
  1771. /*----------------------------------------------------------------------------*/
  1772. static void __exit mpu6050gse_exit(void)
  1773. {
  1774. GSE_FUN();
  1775. }
  1776. /*----------------------------------------------------------------------------*/
  1777. module_init(mpu6050gse_init);
  1778. module_exit(mpu6050gse_exit);
  1779. /*----------------------------------------------------------------------------*/
  1780. MODULE_LICENSE("GPL");
  1781. MODULE_DESCRIPTION("MPU6050 gse driver");
  1782. MODULE_AUTHOR("Yucong.Xiong@mediatek.com");