mpu6050.c.EXPERIMENTAL-checkpatch-fixes 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130
  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_gyro.h>
  14. #include "mpu6050.h"
  15. #include <gyroscope.h>
  16. #include <hwmsensor.h>
  17. #include <mt_boot_common.h>
  18. #define INV_GYRO_AUTO_CALI 1
  19. /*----------------------------------------------------------------------------*/
  20. #define MPU6050_DEFAULT_FS MPU6050_FS_1000
  21. #define MPU6050_DEFAULT_LSB MPU6050_FS_1000_LSB
  22. /*---------------------------------------------------------------------------*/
  23. #define DEBUG 0
  24. /*----------------------------------------------------------------------------*/
  25. #define CONFIG_MPU6050_LOWPASS /*apply low pass filter on output */
  26. /*----------------------------------------------------------------------------*/
  27. #define MPU6050_AXIS_X 0
  28. #define MPU6050_AXIS_Y 1
  29. #define MPU6050_AXIS_Z 2
  30. #define MPU6050_AXES_NUM 3
  31. #define MPU6050_DATA_LEN 6
  32. #define MPU6050_DEV_NAME "MPU6050GY" /* name must different with gsensor mpu6050 */
  33. /*----------------------------------------------------------------------------*/
  34. static const struct i2c_device_id mpu6050_i2c_id[] = {{MPU6050_DEV_NAME, 0}, {} };
  35. int packet_thresh = 75; /* 600 ms / 8ms/sample */
  36. /* Maintain cust info here */
  37. struct gyro_hw gyro_cust;
  38. static struct gyro_hw *hw = &gyro_cust;
  39. struct platform_device *gyroPltFmDev;
  40. /* For driver get cust info */
  41. struct gyro_hw *get_cust_gyro(void)
  42. {
  43. return &gyro_cust;
  44. }
  45. /*----------------------------------------------------------------------------*/
  46. static int mpu6050_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
  47. static int mpu6050_i2c_remove(struct i2c_client *client);
  48. static int mpu6050_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
  49. #if !defined(CONFIG_HAS_EARLYSUSPEND)
  50. static int mpu6050_suspend(struct i2c_client *client, pm_message_t msg);
  51. static int mpu6050_resume(struct i2c_client *client);
  52. #endif
  53. static int mpu6050_local_init(struct platform_device *pdev);
  54. static int mpu6050_remove(void);
  55. static int mpu6050_init_flag = -1; /* 0<==>OK -1 <==> fail */
  56. static struct gyro_init_info mpu6050_init_info = {
  57. .name = "mpu6050GY",
  58. .init = mpu6050_local_init,
  59. .uninit = mpu6050_remove,
  60. };
  61. /*----------------------------------------------------------------------------*/
  62. enum {
  63. GYRO_TRC_FILTER = 0x01,
  64. GYRO_TRC_RAWDATA = 0x02,
  65. GYRO_TRC_IOCTL = 0x04,
  66. GYRO_TRC_CALI = 0X08,
  67. GYRO_TRC_INFO = 0X10,
  68. GYRO_TRC_DATA = 0X20,
  69. };
  70. /*----------------------------------------------------------------------------*/
  71. struct scale_factor {
  72. u8 whole;
  73. u8 fraction;
  74. };
  75. /*----------------------------------------------------------------------------*/
  76. struct data_resolution {
  77. struct scale_factor scalefactor;
  78. int sensitivity;
  79. };
  80. /*----------------------------------------------------------------------------*/
  81. #define C_MAX_FIR_LENGTH (32)
  82. /*----------------------------------------------------------------------------*/
  83. struct data_filter {
  84. s16 raw[C_MAX_FIR_LENGTH][MPU6050_AXES_NUM];
  85. int sum[MPU6050_AXES_NUM];
  86. int num;
  87. int idx;
  88. };
  89. /*----------------------------------------------------------------------------*/
  90. struct mpu6050_i2c_data {
  91. struct i2c_client *client;
  92. struct gyro_hw *hw;
  93. struct hwmsen_convert cvt;
  94. /*misc */
  95. struct data_resolution *reso;
  96. atomic_t trace;
  97. atomic_t suspend;
  98. atomic_t selftest;
  99. atomic_t filter;
  100. s16 cali_sw[MPU6050_AXES_NUM + 1];
  101. /*data */
  102. s8 offset[MPU6050_AXES_NUM + 1]; /*+1: for 4-byte alignment */
  103. s16 data[MPU6050_AXES_NUM + 1];
  104. #if defined(CONFIG_MPU6050_LOWPASS)
  105. atomic_t firlen;
  106. atomic_t fir_en;
  107. struct data_filter fir;
  108. #endif
  109. /*early suspend */
  110. #if defined(CONFIG_HAS_EARLYSUSPEND)
  111. struct early_suspend early_drv;
  112. #endif
  113. #if INV_GYRO_AUTO_CALI == 1
  114. s16 inv_cali_raw[MPU6050_AXES_NUM + 1];
  115. s16 temperature;
  116. struct mutex temperature_mutex; /* for temperature protection */
  117. struct mutex raw_data_mutex; /* for inv_cali_raw[] protection */
  118. #endif
  119. };
  120. #ifdef CONFIG_OF
  121. static const struct of_device_id gyro_of_match[] = {
  122. {.compatible = "mediatek,gyro"},
  123. {},
  124. };
  125. #endif
  126. /*----------------------------------------------------------------------------*/
  127. static struct i2c_driver mpu6050_i2c_driver = {
  128. .driver = {
  129. .name = MPU6050_DEV_NAME,
  130. #ifdef CONFIG_OF
  131. .of_match_table = gyro_of_match,
  132. #endif
  133. },
  134. .probe = mpu6050_i2c_probe,
  135. .remove = mpu6050_i2c_remove,
  136. .detect = mpu6050_i2c_detect,
  137. #if !defined(CONFIG_HAS_EARLYSUSPEND)
  138. .suspend = mpu6050_suspend,
  139. .resume = mpu6050_resume,
  140. #endif
  141. .id_table = mpu6050_i2c_id,
  142. };
  143. /*----------------------------------------------------------------------------*/
  144. static struct i2c_client *mpu6050_i2c_client;
  145. static struct mpu6050_i2c_data *obj_i2c_data;
  146. static bool sensor_power;
  147. /*----------------------------------------------------------------------------*/
  148. #define GYRO_FUN(f) pr_err(GYRO_TAG"%s\n", __func__)
  149. /*----------------------------------------------------------------------------*/
  150. extern int MPU6050_gse_power(void);
  151. extern int MPU6050_gse_mode(void);
  152. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  153. extern int MPU6050_hwmsen_read_block(u8 addr, u8 *buf, u8 len);
  154. extern int MPU6050_hwmsen_write_block(u8 addr, u8 *buf, u8 len);
  155. #endif
  156. static unsigned int power_on;
  157. #if INV_GYRO_AUTO_CALI == 1
  158. /*
  159. devpath : "/sys/devices/virtual/invensense_daemon_class/invensense_daemon_device
  160. class : "/sys/class/invensense_daemon_class"
  161. inv_mpl_motion --
  162. sysfs : "/sys/class/invensense_daemon_class/invensense_daemon_device/inv_mpl_motion", 1:motion 0:no motion
  163. "/sys/devices/virtual/invensense_daemon_class/invensense_daemon_device/inv_mpl_motion", 1:motion 0:no motion
  164. inv_gyro_data_ready --
  165. sysfs : "/sys/class/invensense_daemon_class/invensense_daemon_device/inv_gyro_data_ready"
  166. "/sys/devices/virtual/invensense_daemon_class/invensense_daemon_device/inv_gyro_data_ready"
  167. inv_gyro_power_state --
  168. sysfs : "/sys/class/invensense_daemon_class/invensense_daemon_device/inv_gyro_power_state"
  169. "/sys/devices/virtual/invensense_daemon_class/invensense_daemon_device/inv_gyro_power_state"
  170. */
  171. #define INV_DAEMON_CLASS_NAME "invensense_daemon_class"
  172. #define INV_DAEMON_DEVICE_NAME "invensense_daemon_device"
  173. static struct class *inv_daemon_class;
  174. static struct device *inv_daemon_device;
  175. static int inv_mpl_motion_state; /* default is 0: no motion */
  176. static int inv_gyro_power_state;
  177. static ssize_t inv_mpl_motion_store(struct device *dev,
  178. struct device_attribute *attr, const char *buf, size_t count)
  179. {
  180. unsigned int result;
  181. unsigned long data;
  182. result = kstrtoul(buf, 10, &data);
  183. if (result)
  184. return result;
  185. /* if (inv_mpl_motion_state != data) */
  186. {
  187. char *envp[2];
  188. if (data)
  189. envp[0] = "STATUS=MOTION";
  190. else
  191. envp[0] = "STATUS=NOMOTION";
  192. envp[1] = NULL;
  193. result = kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
  194. inv_mpl_motion_state = data;
  195. }
  196. return count;
  197. }
  198. static ssize_t inv_mpl_motion_show(struct device *dev, struct device_attribute *attr, char *buf)
  199. {
  200. return sprintf(buf, "%d\n", inv_mpl_motion_state);
  201. }
  202. static ssize_t inv_gyro_data_ready_store(struct device *dev,
  203. struct device_attribute *attr, const char *buf,
  204. size_t count)
  205. {
  206. sysfs_notify(&dev->kobj, NULL, "inv_gyro_data_ready");
  207. return count;
  208. }
  209. static ssize_t inv_gyro_data_ready_show(struct device *dev,
  210. struct device_attribute *attr, char *buf)
  211. {
  212. return sprintf(buf, "1\n");
  213. }
  214. static ssize_t inv_gyro_power_state_store(struct device *dev,
  215. struct device_attribute *attr, const char *buf,
  216. size_t count)
  217. {
  218. unsigned int result;
  219. unsigned long data;
  220. result = kstrtoul(buf, 10, &data);
  221. if (result)
  222. return result;
  223. inv_gyro_power_state = data;
  224. sysfs_notify(&dev->kobj, NULL, "inv_gyro_power_state");
  225. return count;
  226. }
  227. static ssize_t inv_gyro_power_state_show(struct device *dev,
  228. struct device_attribute *attr, char *buf)
  229. {
  230. return sprintf(buf, "%d\n", inv_gyro_power_state);
  231. }
  232. static DEVICE_ATTR(inv_mpl_motion, S_IRUGO | S_IWUSR, inv_mpl_motion_show, inv_mpl_motion_store);
  233. static DEVICE_ATTR(inv_gyro_data_ready, S_IRUGO | S_IWUSR, inv_gyro_data_ready_show, inv_gyro_data_ready_store);
  234. static DEVICE_ATTR(inv_gyro_power_state, S_IRUGO | S_IWUSR, inv_gyro_power_state_show, inv_gyro_power_state_store);
  235. static struct device_attribute *inv_daemon_dev_attributes[] = {
  236. &dev_attr_inv_mpl_motion,
  237. &dev_attr_inv_gyro_data_ready,
  238. &dev_attr_inv_gyro_power_state,
  239. };
  240. #endif /* #if INV_GYRO_AUTO_CALI == 1 */
  241. int MPU6050_gyro_power(void)
  242. {
  243. return power_on;
  244. }
  245. EXPORT_SYMBOL(MPU6050_gyro_power);
  246. int MPU6050_gyro_mode(void)
  247. {
  248. return sensor_power;
  249. }
  250. EXPORT_SYMBOL(MPU6050_gyro_mode);
  251. /*--------------------gyroscopy power control function----------------------------------*/
  252. static void MPU6050_power(struct gyro_hw *hw, unsigned int on)
  253. {
  254. }
  255. /*----------------------------------------------------------------------------*/
  256. /*----------------------------------------------------------------------------*/
  257. static int MPU6050_write_rel_calibration(struct mpu6050_i2c_data *obj, int dat[MPU6050_AXES_NUM])
  258. {
  259. obj->cali_sw[MPU6050_AXIS_X] = obj->cvt.sign[MPU6050_AXIS_X]*dat[obj->cvt.map[MPU6050_AXIS_X]];
  260. obj->cali_sw[MPU6050_AXIS_Y] = obj->cvt.sign[MPU6050_AXIS_Y]*dat[obj->cvt.map[MPU6050_AXIS_Y]];
  261. obj->cali_sw[MPU6050_AXIS_Z] = obj->cvt.sign[MPU6050_AXIS_Z]*dat[obj->cvt.map[MPU6050_AXIS_Z]];
  262. #if DEBUG
  263. if (atomic_read(&obj->trace) & GYRO_TRC_CALI)
  264. {
  265. GYRO_LOG("test (%5d, %5d, %5d) ->(%5d, %5d, %5d)->(%5d, %5d, %5d))\n",
  266. obj->cvt.sign[MPU6050_AXIS_X], obj->cvt.sign[MPU6050_AXIS_Y], obj->cvt.sign[MPU6050_AXIS_Z],
  267. dat[MPU6050_AXIS_X], dat[MPU6050_AXIS_Y], dat[MPU6050_AXIS_Z],
  268. obj->cvt.map[MPU6050_AXIS_X], obj->cvt.map[MPU6050_AXIS_Y], obj->cvt.map[MPU6050_AXIS_Z]);
  269. GYRO_LOG("write gyro calibration data (%5d, %5d, %5d)\n",
  270. obj->cali_sw[MPU6050_AXIS_X], obj->cali_sw[MPU6050_AXIS_Y], obj->cali_sw[MPU6050_AXIS_Z]);
  271. }
  272. #endif
  273. return 0;
  274. }
  275. /*----------------------------------------------------------------------------*/
  276. static int MPU6050_ResetCalibration(struct i2c_client *client)
  277. {
  278. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  279. memset(obj->cali_sw, 0x00, sizeof(obj->cali_sw));
  280. return 0;
  281. }
  282. /*----------------------------------------------------------------------------*/
  283. static int MPU6050_ReadCalibration(struct i2c_client *client, int dat[MPU6050_AXES_NUM])
  284. {
  285. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  286. dat[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X]*obj->cali_sw[MPU6050_AXIS_X];
  287. dat[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y]*obj->cali_sw[MPU6050_AXIS_Y];
  288. dat[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z]*obj->cali_sw[MPU6050_AXIS_Z];
  289. #if DEBUG
  290. if (atomic_read(&obj->trace) & GYRO_TRC_CALI) {
  291. GYRO_LOG("Read gyro calibration data (%5d, %5d, %5d)\n",
  292. dat[MPU6050_AXIS_X], dat[MPU6050_AXIS_Y], dat[MPU6050_AXIS_Z]);
  293. }
  294. #endif
  295. return 0;
  296. }
  297. /*----------------------------------------------------------------------------*/
  298. /*----------------------------------------------------------------------------*/
  299. static int MPU6050_WriteCalibration(struct i2c_client *client, int dat[MPU6050_AXES_NUM])
  300. {
  301. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  302. int err = 0;
  303. int cali[MPU6050_AXES_NUM];
  304. GYRO_FUN();
  305. if (!obj || !dat) {
  306. GYRO_ERR("null ptr!!\n");
  307. return -EINVAL;
  308. } else {
  309. cali[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X]*obj->cali_sw[MPU6050_AXIS_X];
  310. cali[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y]*obj->cali_sw[MPU6050_AXIS_Y];
  311. cali[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z]*obj->cali_sw[MPU6050_AXIS_Z];
  312. cali[MPU6050_AXIS_X] += dat[MPU6050_AXIS_X];
  313. cali[MPU6050_AXIS_Y] += dat[MPU6050_AXIS_Y];
  314. cali[MPU6050_AXIS_Z] += dat[MPU6050_AXIS_Z];
  315. #if DEBUG
  316. if (atomic_read(&obj->trace) & GYRO_TRC_CALI) {
  317. GYRO_LOG("write gyro calibration data (%5d, %5d, %5d)-->(%5d, %5d, %5d)\n",
  318. dat[MPU6050_AXIS_X], dat[MPU6050_AXIS_Y], dat[MPU6050_AXIS_Z],
  319. cali[MPU6050_AXIS_X], cali[MPU6050_AXIS_Y], cali[MPU6050_AXIS_Z]);
  320. }
  321. #endif
  322. return MPU6050_write_rel_calibration(obj, cali);
  323. }
  324. return err;
  325. }
  326. /*----------------------------------------------------------------------------*/
  327. /*----------------------------------------------------------------------------*/
  328. static int MPU6050_ReadStart(struct i2c_client *client, bool enable)
  329. {
  330. u8 databuf[2] = { 0 };
  331. int res = 0;
  332. GYRO_FUN();
  333. if (enable) {
  334. /* enable xyz gyro in FIFO */
  335. databuf[0] = (MPU6050_FIFO_GYROX_EN|MPU6050_FIFO_GYROY_EN|MPU6050_FIFO_GYROZ_EN);
  336. } else {
  337. /* disable xyz gyro in FIFO */
  338. databuf[0] = 0;
  339. }
  340. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  341. res = MPU6050_hwmsen_write_block(MPU6050_REG_FIFO_EN, databuf, 0x1);
  342. #else
  343. databuf[1] = databuf[0];
  344. databuf[0] = MPU6050_REG_FIFO_EN;
  345. res = i2c_master_send(client, databuf, 0x2);
  346. #endif
  347. if (res <= 0) {
  348. GYRO_ERR(" enable xyz gyro in FIFO error,enable: 0x%x!\n", databuf[1]);
  349. return MPU6050_ERR_I2C;
  350. }
  351. GYRO_LOG("MPU6050_ReadStart: enable xyz gyro in FIFO: 0x%x\n", databuf[1]);
  352. return MPU6050_SUCCESS;
  353. }
  354. /* ----------------------------------------------------------------------------// */
  355. static int MPU6050_SetPowerMode(struct i2c_client *client, bool enable)
  356. {
  357. u8 databuf[2] = { 0 };
  358. int res = 0;
  359. if (enable == sensor_power) {
  360. GYRO_LOG("Sensor power status is newest!\n");
  361. return MPU6050_SUCCESS;
  362. }
  363. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  364. if (MPU6050_hwmsen_read_block(MPU6050_REG_PWR_CTL, databuf, 0x01))
  365. #else
  366. if (hwmsen_read_byte(client, MPU6050_REG_PWR_CTL, databuf))
  367. #endif
  368. {
  369. GYRO_ERR("read power ctl register err!\n");
  370. return MPU6050_ERR_I2C;
  371. }
  372. databuf[0] &= ~MPU6050_SLEEP;
  373. if (enable == false) {
  374. if (MPU6050_gse_mode() == false)
  375. databuf[0] |= MPU6050_SLEEP;
  376. } else {
  377. /* do nothing */
  378. }
  379. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  380. res = MPU6050_hwmsen_write_block(MPU6050_REG_PWR_CTL, databuf, 0x1);
  381. #else
  382. databuf[1] = databuf[0];
  383. databuf[0] = MPU6050_REG_PWR_CTL;
  384. res = i2c_master_send(client, databuf, 0x2);
  385. #endif
  386. if (res <= 0) {
  387. GYRO_LOG("set power mode failed!\n");
  388. return MPU6050_ERR_I2C;
  389. } else {
  390. GYRO_LOG("set power mode ok %d!\n", enable);
  391. }
  392. sensor_power = enable;
  393. return MPU6050_SUCCESS;
  394. }
  395. /*----------------------------------------------------------------------------*/
  396. static int MPU6050_SetDataFormat(struct i2c_client *client, u8 dataformat)
  397. {
  398. u8 databuf[2] = { 0 };
  399. int res = 0;
  400. GYRO_FUN();
  401. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  402. databuf[0] = dataformat;
  403. res = MPU6050_hwmsen_write_block(MPU6050_REG_CFG, databuf, 0x1);
  404. #else
  405. databuf[0] = MPU6050_REG_CFG;
  406. databuf[1] = dataformat;
  407. res = i2c_master_send(client, databuf, 0x2);
  408. #endif
  409. if (res <= 0)
  410. return MPU6050_ERR_I2C;
  411. /* read sample rate after written for test */
  412. udelay(500);
  413. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  414. if (MPU6050_hwmsen_read_block(MPU6050_REG_CFG, databuf, 0x01))
  415. #else
  416. if (hwmsen_read_byte(client, MPU6050_REG_CFG, databuf))
  417. #endif
  418. {
  419. GYRO_ERR("read data format register err!\n");
  420. return MPU6050_ERR_I2C;
  421. } else {
  422. GYRO_LOG("read data format: 0x%x\n", databuf[0]);
  423. }
  424. return MPU6050_SUCCESS;
  425. }
  426. static int MPU6050_SetFullScale(struct i2c_client *client, u8 dataformat)
  427. {
  428. u8 databuf[2] = { 0 };
  429. int res = 0;
  430. GYRO_FUN();
  431. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  432. databuf[0] = dataformat;
  433. res = MPU6050_hwmsen_write_block(MPU6050_REG_GYRO_CFG, databuf, 0x1);
  434. #else
  435. databuf[0] = MPU6050_REG_GYRO_CFG;
  436. databuf[1] = dataformat;
  437. res = i2c_master_send(client, databuf, 0x2);
  438. #endif
  439. if (res <= 0)
  440. return MPU6050_ERR_I2C;
  441. /* read sample rate after written for test */
  442. udelay(500);
  443. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  444. if (MPU6050_hwmsen_read_block(MPU6050_REG_GYRO_CFG, databuf, 0x01))
  445. #else
  446. if (hwmsen_read_byte(client, MPU6050_REG_GYRO_CFG, databuf))
  447. #endif
  448. {
  449. GYRO_ERR("read data format register err!\n");
  450. return MPU6050_ERR_I2C;
  451. } else {
  452. GYRO_LOG("read data format: 0x%x\n", databuf[0]);
  453. }
  454. return MPU6050_SUCCESS;
  455. }
  456. /* set the sample rate */
  457. static int MPU6050_SetSampleRate(struct i2c_client *client, int sample_rate)
  458. {
  459. u8 databuf[2] = { 0 };
  460. int rate_div = 0;
  461. int res = 0;
  462. GYRO_FUN();
  463. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  464. if (MPU6050_hwmsen_read_block(MPU6050_REG_CFG, databuf, 0x01))
  465. #else
  466. if (hwmsen_read_byte(client, MPU6050_REG_CFG, databuf))
  467. #endif
  468. {
  469. GYRO_ERR("read gyro data format register err!\n");
  470. return MPU6050_ERR_I2C;
  471. } else {
  472. GYRO_LOG("read gyro data format register: 0x%x\n", databuf[0]);
  473. }
  474. if ((databuf[0] & 0x07) == 0) { /* Analog sample rate is 8KHz */
  475. rate_div = 8 * 1024 / sample_rate - 1;
  476. } else { /* 1kHz */
  477. rate_div = 1024 / sample_rate - 1;
  478. }
  479. if (rate_div > 255) { /* rate_div: 0 to 255; */
  480. rate_div = 255;
  481. } else if (rate_div < 0) {
  482. rate_div = 0;
  483. }
  484. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  485. databuf[0] = rate_div;
  486. res = MPU6050_hwmsen_write_block(MPU6050_REG_SAMRT_DIV, databuf, 0x1);
  487. #else
  488. databuf[0] = MPU6050_REG_SAMRT_DIV;
  489. databuf[1] = rate_div;
  490. res = i2c_master_send(client, databuf, 0x2);
  491. #endif
  492. if (res <= 0) {
  493. GYRO_ERR("write sample rate register err!\n");
  494. return MPU6050_ERR_I2C;
  495. }
  496. /* read sample div after written for test */
  497. udelay(500);
  498. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  499. if (MPU6050_hwmsen_read_block(MPU6050_REG_SAMRT_DIV, databuf, 0x01))
  500. #else
  501. if (hwmsen_read_byte(client, MPU6050_REG_SAMRT_DIV, databuf))
  502. #endif
  503. {
  504. GYRO_ERR("read gyro sample rate register err!\n");
  505. return MPU6050_ERR_I2C;
  506. } else {
  507. GYRO_LOG("read gyro sample rate: 0x%x\n", databuf[0]);
  508. }
  509. return MPU6050_SUCCESS;
  510. }
  511. /*----------------------------------------------------------------------------*/
  512. /*----------------------------------------------------------------------------*/
  513. static int MPU6050_FIFOConfig(struct i2c_client *client, u8 clk)
  514. {
  515. u8 databuf[2] = { 0 };
  516. int res = 0;
  517. GYRO_FUN();
  518. /* use gyro X, Y or Z for clocking */
  519. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  520. databuf[0] = clk;
  521. res = MPU6050_hwmsen_write_block(MPU6050_REG_PWR_CTL, databuf, 0x1);
  522. #else
  523. databuf[0] = MPU6050_REG_PWR_CTL;
  524. databuf[1] = clk;
  525. res = i2c_master_send(client, databuf, 0x2);
  526. #endif
  527. if (res <= 0) {
  528. GYRO_ERR("write Power CTRL register err!\n");
  529. return MPU6050_ERR_I2C;
  530. }
  531. GYRO_LOG("MPU6050 use gyro X for clocking OK!\n");
  532. mdelay(50);
  533. /* enable xyz gyro in FIFO */
  534. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  535. databuf[0] = (MPU6050_FIFO_GYROX_EN|MPU6050_FIFO_GYROY_EN|MPU6050_FIFO_GYROZ_EN);
  536. res = MPU6050_hwmsen_write_block(MPU6050_REG_FIFO_EN, databuf, 0x1);
  537. #else
  538. databuf[0] = MPU6050_REG_FIFO_EN;
  539. databuf[1] = (MPU6050_FIFO_GYROX_EN|MPU6050_FIFO_GYROY_EN|MPU6050_FIFO_GYROZ_EN);
  540. res = i2c_master_send(client, databuf, 0x2);
  541. #endif
  542. if (res <= 0) {
  543. GYRO_ERR("write Power CTRL register err!\n");
  544. return MPU6050_ERR_I2C;
  545. }
  546. GYRO_LOG("MPU6050 enable xyz gyro in FIFO OK!\n");
  547. /* disable AUX_VDDIO */
  548. databuf[0] = MPU6050_REG_AUX_VDD;
  549. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  550. databuf[0] = MPU6050_AUX_VDDIO_DIS;
  551. res = MPU6050_hwmsen_write_block(MPU6050_REG_AUX_VDD, databuf, 0x1);
  552. #else
  553. databuf[0] = MPU6050_REG_AUX_VDD;
  554. databuf[1] = MPU6050_AUX_VDDIO_DIS;
  555. res = i2c_master_send(client, databuf, 0x2);
  556. #endif
  557. if (res <= 0) {
  558. GYRO_ERR("write AUX_VDD register err!\n");
  559. return MPU6050_ERR_I2C;
  560. }
  561. GYRO_LOG("MPU6050 disable AUX_VDDIO OK!\n");
  562. /* enable FIFO and reset FIFO */
  563. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  564. databuf[0] = (MPU6050_FIFO_EN | MPU6050_FIFO_RST);
  565. res = MPU6050_hwmsen_write_block(MPU6050_REG_FIFO_CTL, databuf, 0x1);
  566. #else
  567. databuf[0] = MPU6050_REG_FIFO_CTL;
  568. databuf[1] = (MPU6050_FIFO_EN | MPU6050_FIFO_RST);
  569. res = i2c_master_send(client, databuf, 0x2);
  570. #endif
  571. if (res <= 0)
  572. {
  573. GYRO_ERR("write FIFO CTRL register err!\n");
  574. return MPU6050_ERR_I2C;
  575. }
  576. GYRO_LOG("MPU6050_FIFOConfig OK!\n");
  577. return MPU6050_SUCCESS;
  578. }
  579. /*----------------------------------------------------------------------------*/
  580. static int MPU6050_ReadFifoData(struct i2c_client *client, s16 *data, int *datalen)
  581. {
  582. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  583. u8 buf[MPU6050_DATA_LEN] = {0};
  584. s16 tmp1[MPU6050_AXES_NUM] = {0};
  585. s16 tmp2[MPU6050_AXES_NUM] = {0};
  586. int err = 0;
  587. u8 tmp = 0;
  588. int packet_cnt = 0;
  589. int i;
  590. GYRO_FUN();
  591. if (NULL == client)
  592. {
  593. return -EINVAL;
  594. }
  595. /* stop putting data in FIFO */
  596. MPU6050_ReadStart(client, false);
  597. /* read data number of bytes in FIFO */
  598. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  599. err = MPU6050_hwmsen_read_block(MPU6050_REG_FIFO_CNTH, &tmp, 0x01);
  600. #else
  601. err = hwmsen_read_byte(client, MPU6050_REG_FIFO_CNTH, &tmp);
  602. #endif
  603. if (err)
  604. {
  605. GYRO_ERR("read data high number of bytes error: %d\n", err);
  606. return -1;
  607. }
  608. packet_cnt = tmp << 8;
  609. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  610. err = MPU6050_hwmsen_read_block(MPU6050_REG_FIFO_CNTL, &tmp, 0x01);
  611. #else
  612. err = hwmsen_read_byte(client, MPU6050_REG_FIFO_CNTL, &tmp);
  613. #endif
  614. if (err)
  615. {
  616. GYRO_ERR("read data low number of bytes error: %d\n", err);
  617. return -1;
  618. }
  619. packet_cnt = (packet_cnt + tmp) / MPU6050_DATA_LEN;
  620. GYRO_LOG("MPU6050 Read Data packet number OK: %d\n", packet_cnt);
  621. *datalen = packet_cnt;
  622. /* Within +-5% range: timing_tolerance * packet_thresh=0.05*75 */
  623. if (packet_cnt && (abs(packet_thresh - packet_cnt) < 4))
  624. {
  625. /* read data in FIFO */
  626. for (i = 0; i < packet_cnt; i++)
  627. {
  628. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  629. if (MPU6050_hwmsen_read_block(MPU6050_REG_FIFO_DATA, buf, MPU6050_DATA_LEN))
  630. #else
  631. if (hwmsen_read_block(client, MPU6050_REG_FIFO_DATA, buf, MPU6050_DATA_LEN))
  632. #endif
  633. {
  634. GYRO_ERR("MPU6050 read data from FIFO error: %d\n", err);
  635. return -2;
  636. }
  637. else
  638. {
  639. GYRO_LOG("MPU6050 read Data of diff address from FIFO OK !\n");
  640. }
  641. tmp1[MPU6050_AXIS_X] = (s16)((buf[MPU6050_AXIS_X*2+1]) | (buf[MPU6050_AXIS_X*2] << 8));
  642. tmp1[MPU6050_AXIS_Y] = (s16)((buf[MPU6050_AXIS_Y*2+1]) | (buf[MPU6050_AXIS_Y*2] << 8));
  643. tmp1[MPU6050_AXIS_Z] = (s16)((buf[MPU6050_AXIS_Z*2+1]) | (buf[MPU6050_AXIS_Z*2] << 8));
  644. /* remap coordinate// */
  645. tmp2[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X]*tmp1[MPU6050_AXIS_X];
  646. tmp2[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y]*tmp1[MPU6050_AXIS_Y];
  647. tmp2[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z]*tmp1[MPU6050_AXIS_Z];
  648. data[3 * i + MPU6050_AXIS_X] = tmp2[MPU6050_AXIS_X];
  649. data[3 * i + MPU6050_AXIS_Y] = tmp2[MPU6050_AXIS_Y];
  650. data[3 * i + MPU6050_AXIS_Z] = tmp2[MPU6050_AXIS_Z];
  651. GYRO_LOG("gyro FIFO packet[%d]:[%04X %04X %04X] => [%5d %5d %5d]\n", i,
  652. data[3*i + MPU6050_AXIS_X], data[3*i + MPU6050_AXIS_Y], data[3*i + MPU6050_AXIS_Z],
  653. data[3*i + MPU6050_AXIS_X], data[3*i + MPU6050_AXIS_Y], data[3*i + MPU6050_AXIS_Z]);
  654. }
  655. }
  656. else
  657. {
  658. GYRO_ERR("MPU6050 Incorrect packet count: %d\n", packet_cnt);
  659. return -3;
  660. }
  661. return 0;
  662. }
  663. /*----------------------------------------------------------------------------*/
  664. static int MPU6050_ReadGyroData(struct i2c_client *client, char *buf, int bufsize)
  665. {
  666. char databuf[6];
  667. int data[3];
  668. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  669. if (sensor_power == false)
  670. {
  671. MPU6050_SetPowerMode(client, true);
  672. msleep(50);
  673. }
  674. #if INV_GYRO_AUTO_CALI == 1
  675. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  676. if (MPU6050_hwmsen_read_block(MPU6050_REG_TEMPH, databuf, 2))
  677. #else
  678. if (hwmsen_read_block(client, MPU6050_REG_TEMPH, databuf, 2))
  679. #endif
  680. {
  681. GYRO_ERR("MPU6050 read temperature data error\n");
  682. return -2;
  683. }
  684. else
  685. {
  686. mutex_lock(&obj->temperature_mutex);
  687. obj->temperature = ((s16)((databuf[1]) | (databuf[0] << 8)));
  688. mutex_unlock(&obj->temperature_mutex);
  689. }
  690. #endif
  691. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  692. if (MPU6050_hwmsen_read_block(MPU6050_REG_GYRO_XH, databuf, 6))
  693. #else
  694. if (hwmsen_read_block(client, MPU6050_REG_GYRO_XH, databuf, 6))
  695. #endif
  696. {
  697. GYRO_ERR("MPU6050 read gyroscope data error\n");
  698. return -2;
  699. }
  700. else
  701. {
  702. obj->data[MPU6050_AXIS_X] = ((s16)((databuf[MPU6050_AXIS_X*2+1]) | (databuf[MPU6050_AXIS_X*2] << 8)));
  703. obj->data[MPU6050_AXIS_Y] = ((s16)((databuf[MPU6050_AXIS_Y*2+1]) | (databuf[MPU6050_AXIS_Y*2] << 8)));
  704. obj->data[MPU6050_AXIS_Z] = ((s16)((databuf[MPU6050_AXIS_Z*2+1]) | (databuf[MPU6050_AXIS_Z*2] << 8)));
  705. #if DEBUG
  706. if (atomic_read(&obj->trace) & GYRO_TRC_RAWDATA)
  707. {
  708. GYRO_LOG("read gyro register: %d, %d, %d, %d, %d, %d",
  709. databuf[0], databuf[1], databuf[2], databuf[3], databuf[4], databuf[5]);
  710. GYRO_LOG("get gyro raw data (0x%08X, 0x%08X, 0x%08X) -> (%5d, %5d, %5d)\n",
  711. obj->data[MPU6050_AXIS_X], obj->data[MPU6050_AXIS_Y], obj->data[MPU6050_AXIS_Z],
  712. obj->data[MPU6050_AXIS_X], obj->data[MPU6050_AXIS_Y], obj->data[MPU6050_AXIS_Z]);
  713. }
  714. #endif
  715. #if INV_GYRO_AUTO_CALI == 1
  716. mutex_lock(&obj->raw_data_mutex);
  717. /*remap coordinate*/
  718. obj->inv_cali_raw[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X]*obj->data[MPU6050_AXIS_X];
  719. obj->inv_cali_raw[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y]*obj->data[MPU6050_AXIS_Y];
  720. obj->inv_cali_raw[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z]*obj->data[MPU6050_AXIS_Z];
  721. mutex_unlock(&obj->raw_data_mutex);
  722. #endif
  723. obj->data[MPU6050_AXIS_X] = obj->data[MPU6050_AXIS_X] + obj->cali_sw[MPU6050_AXIS_X];
  724. obj->data[MPU6050_AXIS_Y] = obj->data[MPU6050_AXIS_Y] + obj->cali_sw[MPU6050_AXIS_Y];
  725. obj->data[MPU6050_AXIS_Z] = obj->data[MPU6050_AXIS_Z] + obj->cali_sw[MPU6050_AXIS_Z];
  726. /*remap coordinate*/
  727. data[obj->cvt.map[MPU6050_AXIS_X]] = obj->cvt.sign[MPU6050_AXIS_X]*obj->data[MPU6050_AXIS_X];
  728. data[obj->cvt.map[MPU6050_AXIS_Y]] = obj->cvt.sign[MPU6050_AXIS_Y]*obj->data[MPU6050_AXIS_Y];
  729. data[obj->cvt.map[MPU6050_AXIS_Z]] = obj->cvt.sign[MPU6050_AXIS_Z]*obj->data[MPU6050_AXIS_Z];
  730. /* Out put the degree/second(o/s) */
  731. data[MPU6050_AXIS_X] = data[MPU6050_AXIS_X] * MPU6050_FS_MAX_LSB / MPU6050_DEFAULT_LSB;
  732. data[MPU6050_AXIS_Y] = data[MPU6050_AXIS_Y] * MPU6050_FS_MAX_LSB / MPU6050_DEFAULT_LSB;
  733. data[MPU6050_AXIS_Z] = data[MPU6050_AXIS_Z] * MPU6050_FS_MAX_LSB / MPU6050_DEFAULT_LSB;
  734. }
  735. sprintf(buf, "%04x %04x %04x", data[MPU6050_AXIS_X], data[MPU6050_AXIS_Y], data[MPU6050_AXIS_Z]);
  736. #if DEBUG
  737. if (atomic_read(&obj->trace) & GYRO_TRC_DATA)
  738. {
  739. GYRO_LOG("get gyro data packet:[%d %d %d]\n", data[0], data[1], data[2]);
  740. }
  741. #endif
  742. return 0;
  743. }
  744. /* for factory mode */
  745. static int MPU6050_PROCESS_SMT_DATA(struct i2c_client *client, short *data)
  746. {
  747. int total_num = 0;
  748. int retval = 0;
  749. long xSum = 0;
  750. long ySum = 0;
  751. long zSum = 0;
  752. long xAvg, yAvg, zAvg;
  753. long xRMS, yRMS, zRMS;
  754. int i = 0;
  755. int bias_thresh = 5242; /* 40 dps * 131.072 LSB/dps */
  756. /* float RMS_thresh = 687.19f; // (.2 dps * 131.072) ^ 2 */
  757. long RMS_thresh = 68719; /* (.2 dps * 131.072) ^ 2 */
  758. total_num = data[0];
  759. retval = data[1];
  760. GYRO_LOG("MPU6050 read gyro data OK, total number: %d\n", total_num);
  761. for (i = 0; i < total_num; i++)
  762. {
  763. xSum = xSum + data[MPU6050_AXES_NUM*i + MPU6050_AXIS_X + 2];
  764. ySum = ySum + data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Y + 2];
  765. zSum = zSum + data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Z + 2];
  766. /*
  767. FLPLOGD("read gyro data OK: packet_num:%d, [X:%5d, Y:%5d, Z:%5d]\n", i, data[MPU6050_AXES_NUM*i + MPU6050_AXIS_X +2], data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Y +2], data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Z +2]);
  768. FLPLOGD("MPU6050 xSum: %5d, ySum: %5d, zSum: %5d\n", xSum, ySum, zSum);
  769. */
  770. }
  771. GYRO_LOG("MPU6050 xSum: %5ld, ySum: %5ld, zSum: %5ld\n", xSum, ySum, zSum);
  772. if (total_num != 0)
  773. {
  774. xAvg = (xSum / total_num);
  775. yAvg = (ySum / total_num);
  776. zAvg = (zSum / total_num);
  777. }
  778. else
  779. {
  780. xAvg = xSum;
  781. yAvg = ySum;
  782. zAvg = zSum;
  783. }
  784. GYRO_LOG("MPU6050 xAvg: %ld, yAvg: %ld, zAvg: %ld\n", xAvg, yAvg, zAvg);
  785. if (abs(xAvg) > bias_thresh)
  786. {
  787. GYRO_LOG("X-Gyro bias exceeded threshold\n");
  788. retval |= 1 << 3;
  789. }
  790. if (abs(yAvg) > bias_thresh)
  791. {
  792. GYRO_LOG("Y-Gyro bias exceeded threshold\n");
  793. retval |= 1 << 4;
  794. }
  795. if (abs(zAvg) > bias_thresh)
  796. {
  797. GYRO_LOG("Z-Gyro bias exceeded threshold\n");
  798. retval |= 1 << 5;
  799. }
  800. xRMS = 0;
  801. yRMS = 0;
  802. zRMS = 0;
  803. /* Finally, check RMS */
  804. for (i = 0; i < total_num; i++)
  805. {
  806. xRMS += (data[MPU6050_AXES_NUM*i + MPU6050_AXIS_X+2]-xAvg)*(data[MPU6050_AXES_NUM*i + MPU6050_AXIS_X+2]-xAvg);
  807. yRMS += (data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Y+2]-yAvg)*(data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Y+2]-yAvg);
  808. zRMS += (data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Z+2]-zAvg)*(data[MPU6050_AXES_NUM*i + MPU6050_AXIS_Z+2]-zAvg);
  809. }
  810. GYRO_LOG("MPU6050 xRMS: %ld, yRMS: %ld, zRMS: %ld\n", xRMS, yRMS, zRMS);
  811. xRMS = 100*xRMS;
  812. yRMS = 100*yRMS;
  813. zRMS = 100*zRMS;
  814. if (FACTORY_BOOT == get_boot_mode())
  815. return retval;
  816. if (xRMS > RMS_thresh * total_num)
  817. {
  818. GYRO_LOG("X-Gyro RMS exceeded threshold, RMS_thresh: %ld\n", RMS_thresh * total_num);
  819. retval |= 1 << 6;
  820. }
  821. if (yRMS > RMS_thresh * total_num)
  822. {
  823. GYRO_LOG("Y-Gyro RMS exceeded threshold, RMS_thresh: %ld\n", RMS_thresh * total_num);
  824. retval |= 1 << 7;
  825. }
  826. if (zRMS > RMS_thresh * total_num)
  827. {
  828. GYRO_LOG("Z-Gyro RMS exceeded threshold, RMS_thresh: %ld\n", RMS_thresh * total_num);
  829. retval |= 1 << 8;
  830. }
  831. if (xRMS == 0 || yRMS == 0 || zRMS == 0)
  832. /* If any of the RMS noise value returns zero, then we might have dead gyro or FIFO/register failure */
  833. retval |= 1 << 9;
  834. GYRO_LOG("retval %d\n", retval);
  835. return retval;
  836. }
  837. /*----------------------------------------------------------------------------*/
  838. static int MPU6050_SMTReadSensorData(struct i2c_client *client, s16 *buf, int bufsize)
  839. {
  840. /* S16 gyro[MPU6050_AXES_NUM*MPU6050_FIFOSIZE]; */
  841. int res = 0;
  842. int i;
  843. int datalen, total_num = 0;
  844. GYRO_FUN();
  845. if (sensor_power == false)
  846. {
  847. MPU6050_SetPowerMode(client, true);
  848. }
  849. if (NULL == buf)
  850. {
  851. return -1;
  852. }
  853. if (NULL == client)
  854. {
  855. *buf = 0;
  856. return -2;
  857. }
  858. for (i = 0; i < MPU6050_AXES_NUM; i++)
  859. {
  860. res = MPU6050_FIFOConfig(client, (i+1));
  861. if (res)
  862. {
  863. GYRO_ERR("MPU6050_FIFOConfig error:%d!\n", res);
  864. return -3;
  865. }
  866. /* putting data in FIFO during the delayed 600ms */
  867. mdelay(600);
  868. res = MPU6050_ReadFifoData(client, &(buf[total_num+2]), &datalen);
  869. if (res)
  870. {
  871. if (res == (-3))
  872. {
  873. buf[1] = (1 << i);
  874. }
  875. else
  876. {
  877. GYRO_ERR("MPU6050_ReadData error:%d!\n", res);
  878. return -3;
  879. }
  880. }
  881. else
  882. {
  883. buf[0] = datalen;
  884. total_num += datalen*MPU6050_AXES_NUM;
  885. }
  886. }
  887. GYRO_LOG("gyroscope read data OK, total packet: %d", buf[0]);
  888. return 0;
  889. }
  890. /*----------------------------------------------------------------------------*/
  891. static int MPU6050_ReadChipInfo(struct i2c_client *client, char *buf, int bufsize)
  892. {
  893. u8 databuf[10];
  894. memset(databuf, 0, sizeof(u8)*10);
  895. if ((NULL == buf) || (bufsize <= 30))
  896. {
  897. return -1;
  898. }
  899. if (NULL == client)
  900. {
  901. *buf = 0;
  902. return -2;
  903. }
  904. sprintf(buf, "MPU6050 Chip");
  905. return 0;
  906. }
  907. #if INV_GYRO_AUTO_CALI == 1
  908. /*----------------------------------------------------------------------------*/
  909. static int MPU6050_ReadGyroDataRaw(struct i2c_client *client, char *buf, int bufsize)
  910. {
  911. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  912. mutex_lock(&obj->raw_data_mutex);
  913. /* return gyro raw LSB in device orientation */
  914. sprintf(buf, "%x %x %x", obj->inv_cali_raw[MPU6050_AXIS_X], obj->inv_cali_raw[MPU6050_AXIS_Y], obj->inv_cali_raw[MPU6050_AXIS_Z]);
  915. #if DEBUG
  916. if (atomic_read(&obj->trace) & GYRO_TRC_DATA)
  917. {
  918. GYRO_LOG("get gyro raw data packet:[%d %d %d]\n", obj->inv_cali_raw[0], obj->inv_cali_raw[1], obj->inv_cali_raw[2]);
  919. }
  920. #endif
  921. mutex_unlock(&obj->raw_data_mutex);
  922. return 0;
  923. }
  924. /*----------------------------------------------------------------------------*/
  925. static int MPU6050_ReadTemperature(struct i2c_client *client, char *buf, int bufsize)
  926. {
  927. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  928. mutex_lock(&obj->temperature_mutex);
  929. sprintf(buf, "%x", obj->temperature);
  930. #if DEBUG
  931. if (atomic_read(&obj->trace) & GYRO_TRC_DATA)
  932. {
  933. GYRO_LOG("get gyro temperature:[%d]\n", obj->temperature);
  934. }
  935. #endif
  936. mutex_unlock(&obj->temperature_mutex);
  937. return 0;
  938. }
  939. /*----------------------------------------------------------------------------*/
  940. static int MPU6050_ReadPowerStatus(struct i2c_client *client, char *buf, int bufsize)
  941. {
  942. #if DEBUG
  943. GYRO_LOG("get gyro PowerStatus:[%d]\n", sensor_power);
  944. #endif
  945. sprintf(buf, "%x", sensor_power);
  946. return 0;
  947. }
  948. #endif
  949. /*----------------------------------------------------------------------------*/
  950. static ssize_t show_chipinfo_value(struct device_driver *ddri, char *buf)
  951. {
  952. struct i2c_client *client = mpu6050_i2c_client;
  953. char strbuf[MPU6050_BUFSIZE];
  954. if (NULL == client)
  955. {
  956. GYRO_ERR("i2c client is null!!\n");
  957. return 0;
  958. }
  959. MPU6050_ReadChipInfo(client, strbuf, MPU6050_BUFSIZE);
  960. return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
  961. }
  962. /*----------------------------------------------------------------------------*/
  963. static ssize_t show_sensordata_value(struct device_driver *ddri, char *buf)
  964. {
  965. struct i2c_client *client = mpu6050_i2c_client;
  966. char strbuf[MPU6050_BUFSIZE];
  967. if (NULL == client)
  968. {
  969. GYRO_ERR("i2c client is null!!\n");
  970. return 0;
  971. }
  972. MPU6050_ReadGyroData(client, strbuf, MPU6050_BUFSIZE);
  973. return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
  974. }
  975. /*----------------------------------------------------------------------------*/
  976. static ssize_t show_trace_value(struct device_driver *ddri, char *buf)
  977. {
  978. ssize_t res;
  979. struct mpu6050_i2c_data *obj = obj_i2c_data;
  980. if (obj == NULL)
  981. {
  982. GYRO_ERR("i2c_data obj is null!!\n");
  983. return 0;
  984. }
  985. res = snprintf(buf, PAGE_SIZE, "0x%04X\n", atomic_read(&obj->trace));
  986. return res;
  987. }
  988. /*----------------------------------------------------------------------------*/
  989. static ssize_t store_trace_value(struct device_driver *ddri, const char *buf, size_t count)
  990. {
  991. struct mpu6050_i2c_data *obj = obj_i2c_data;
  992. int trace;
  993. if (obj == NULL)
  994. {
  995. GYRO_ERR("i2c_data obj is null!!\n");
  996. return 0;
  997. }
  998. if (1 == sscanf(buf, "0x%x", &trace))
  999. {
  1000. atomic_set(&obj->trace, trace);
  1001. }
  1002. else
  1003. {
  1004. GYRO_ERR("invalid content: '%s', length = %zu\n", buf, count);
  1005. }
  1006. return count;
  1007. }
  1008. /*----------------------------------------------------------------------------*/
  1009. static ssize_t show_status_value(struct device_driver *ddri, char *buf)
  1010. {
  1011. ssize_t len = 0;
  1012. struct mpu6050_i2c_data *obj = obj_i2c_data;
  1013. if (obj == NULL)
  1014. {
  1015. GYRO_ERR("i2c_data obj is null!!\n");
  1016. return 0;
  1017. }
  1018. if (obj->hw)
  1019. {
  1020. len += snprintf(buf+len, PAGE_SIZE-len, "CUST: %d %d (%d %d)\n",
  1021. obj->hw->i2c_num, obj->hw->direction, obj->hw->power_id, obj->hw->power_vol);
  1022. }
  1023. else
  1024. {
  1025. len += snprintf(buf+len, PAGE_SIZE-len, "CUST: NULL\n");
  1026. }
  1027. return len;
  1028. }
  1029. /*----------------------------------------------------------------------------*/
  1030. static DRIVER_ATTR(chipinfo, S_IRUGO, show_chipinfo_value, NULL);
  1031. static DRIVER_ATTR(sensordata, S_IRUGO, show_sensordata_value, NULL);
  1032. static DRIVER_ATTR(trace, S_IWUSR | S_IRUGO, show_trace_value, store_trace_value);
  1033. static DRIVER_ATTR(status, S_IRUGO, show_status_value, NULL);
  1034. /*----------------------------------------------------------------------------*/
  1035. static struct driver_attribute *MPU6050_attr_list[] = {
  1036. &driver_attr_chipinfo, /*chip information*/
  1037. &driver_attr_sensordata, /*dump sensor data*/
  1038. &driver_attr_trace, /*trace log*/
  1039. &driver_attr_status,
  1040. };
  1041. /*----------------------------------------------------------------------------*/
  1042. static int mpu6050_create_attr(struct device_driver *driver)
  1043. {
  1044. int idx, err = 0;
  1045. int num = (int)(sizeof(MPU6050_attr_list) / sizeof(MPU6050_attr_list[0]));
  1046. if (driver == NULL)
  1047. return -EINVAL;
  1048. for (idx = 0; idx < num; idx++) {
  1049. err = driver_create_file(driver, MPU6050_attr_list[idx]);
  1050. if (0 != err) {
  1051. GYRO_ERR("driver_create_file (%s) = %d\n",
  1052. MPU6050_attr_list[idx]->attr.name, err);
  1053. break;
  1054. }
  1055. }
  1056. return err;
  1057. }
  1058. /*----------------------------------------------------------------------------*/
  1059. static int mpu6050_delete_attr(struct device_driver *driver)
  1060. {
  1061. int idx, err = 0;
  1062. int num = (int)(sizeof(MPU6050_attr_list) / sizeof(MPU6050_attr_list[0]));
  1063. if (driver == NULL)
  1064. return -EINVAL;
  1065. for (idx = 0; idx < num; idx++)
  1066. driver_remove_file(driver, MPU6050_attr_list[idx]);
  1067. return err;
  1068. }
  1069. /*----------------------------------------------------------------------------*/
  1070. static int mpu6050_gpio_config(void)
  1071. {
  1072. /* because we donot use EINT ,to support low power */
  1073. /* config to GPIO input mode + PD */
  1074. /* set GPIO_MSE_EINT_PIN */
  1075. /*
  1076. mt_set_gpio_mode(GPIO_GYRO_EINT_PIN, GPIO_GYRO_EINT_PIN_M_GPIO);
  1077. mt_set_gpio_dir(GPIO_GYRO_EINT_PIN, GPIO_DIR_IN);
  1078. mt_set_gpio_pull_enable(GPIO_GYRO_EINT_PIN, GPIO_PULL_ENABLE);
  1079. mt_set_gpio_pull_select(GPIO_GYRO_EINT_PIN, GPIO_PULL_DOWN);
  1080. */
  1081. return 0;
  1082. }
  1083. static int mpu6050_init_client(struct i2c_client *client, bool enable)
  1084. {
  1085. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1086. int res = 0;
  1087. GYRO_FUN();
  1088. mpu6050_gpio_config();
  1089. res = MPU6050_SetPowerMode(client, true);
  1090. if (res != MPU6050_SUCCESS)
  1091. return res;
  1092. /* The range should at least be 17.45 rad/s (ie: ~1000 deg/s). */
  1093. res = MPU6050_SetDataFormat(client, (MPU6050_SYNC_GYROX << MPU6050_EXT_SYNC) |
  1094. MPU6050_RATE_1K_LPFB_188HZ);
  1095. res = MPU6050_SetFullScale(client, (MPU6050_DEFAULT_FS << MPU6050_FS_RANGE));
  1096. if (res != MPU6050_SUCCESS)
  1097. return res;
  1098. /* Set 125HZ sample rate */
  1099. res = MPU6050_SetSampleRate(client, 125);
  1100. if (res != MPU6050_SUCCESS)
  1101. return res;
  1102. res = MPU6050_SetPowerMode(client, enable);
  1103. if (res != MPU6050_SUCCESS)
  1104. return res;
  1105. GYRO_LOG("mpu6050_init_client OK!\n");
  1106. #ifdef CONFIG_MPU6050_LOWPASS
  1107. memset(&obj->fir, 0x00, sizeof(obj->fir));
  1108. #endif
  1109. return MPU6050_SUCCESS;
  1110. }
  1111. /*----------------------------------------------------------------------------*/
  1112. int mpu6050_operate(void *self, uint32_t command, void *buff_in, int size_in,
  1113. void *buff_out, int size_out, int *actualout)
  1114. {
  1115. int err = 0;
  1116. int value;
  1117. struct mpu6050_i2c_data *priv = (struct mpu6050_i2c_data *)self;
  1118. struct hwm_sensor_data *gyro_data;
  1119. char buff[MPU6050_BUFSIZE];
  1120. switch (command) {
  1121. case SENSOR_DELAY:
  1122. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1123. GYRO_ERR("Set delay parameter error!\n");
  1124. err = -EINVAL;
  1125. } else {
  1126. }
  1127. break;
  1128. case SENSOR_ENABLE:
  1129. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1130. GYRO_ERR("Enable gyroscope parameter error!\n");
  1131. err = -EINVAL;
  1132. } else {
  1133. value = *(int *)buff_in;
  1134. if (((value == 0) && (sensor_power == false))
  1135. || ((value == 1) && (sensor_power == true))) {
  1136. GYRO_LOG("gyroscope device have updated!\n");
  1137. } else {
  1138. err = MPU6050_SetPowerMode(priv->client, !sensor_power);
  1139. }
  1140. #if INV_GYRO_AUTO_CALI == 1
  1141. inv_gyro_power_state = sensor_power;
  1142. /* put this in where gyro power is changed, waking up mpu daemon */
  1143. sysfs_notify(&inv_daemon_device->kobj, NULL, "inv_gyro_power_state");
  1144. #endif
  1145. }
  1146. break;
  1147. case SENSOR_GET_DATA:
  1148. if ((buff_out == NULL) || (size_out < sizeof(struct hwm_sensor_data))) {
  1149. GYRO_ERR("get gyroscope data parameter error!\n");
  1150. err = -EINVAL;
  1151. } else {
  1152. gyro_data = (struct hwm_sensor_data *) buff_out;
  1153. err = MPU6050_ReadGyroData(priv->client, buff, MPU6050_BUFSIZE);
  1154. if (!err) {
  1155. sscanf(buff, "%x %x %x", &gyro_data->values[0],
  1156. &gyro_data->values[1], &gyro_data->values[2]);
  1157. gyro_data->status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1158. gyro_data->value_divide = DEGREE_TO_RAD;
  1159. #if INV_GYRO_AUTO_CALI == 1
  1160. /* put this in where gyro data is ready to report to hal, waking up mpu daemon */
  1161. sysfs_notify(&inv_daemon_device->kobj, NULL, "inv_gyro_data_ready");
  1162. #endif
  1163. }
  1164. }
  1165. break;
  1166. default:
  1167. GYRO_ERR("gyroscope operate function no this parameter %d!\n", command);
  1168. err = -1;
  1169. break;
  1170. }
  1171. return err;
  1172. }
  1173. /******************************************************************************
  1174. * Function Configuration
  1175. ******************************************************************************/
  1176. static int mpu6050_open(struct inode *inode, struct file *file)
  1177. {
  1178. file->private_data = mpu6050_i2c_client;
  1179. if (file->private_data == NULL) {
  1180. GYRO_ERR("null pointer!!\n");
  1181. return -EINVAL;
  1182. }
  1183. return nonseekable_open(inode, file);
  1184. }
  1185. /*----------------------------------------------------------------------------*/
  1186. static int mpu6050_release(struct inode *inode, struct file *file)
  1187. {
  1188. file->private_data = NULL;
  1189. return 0;
  1190. }
  1191. /*----------------------------------------------------------------------------*/
  1192. static long mpu6050_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  1193. {
  1194. struct i2c_client *client = (struct i2c_client *)file->private_data;
  1195. char strbuf[MPU6050_BUFSIZE] = { 0 };
  1196. s16 *SMTdata;
  1197. void __user *data;
  1198. long err = 0;
  1199. int copy_cnt = 0;
  1200. struct SENSOR_DATA sensor_data;
  1201. int cali[3];
  1202. int smtRes = 0;
  1203. if (_IOC_DIR(cmd) & _IOC_READ)
  1204. err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
  1205. else if (_IOC_DIR(cmd) & _IOC_WRITE)
  1206. err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
  1207. if (err) {
  1208. GYRO_ERR("access error: %08X, (%2d, %2d)\n", cmd, _IOC_DIR(cmd), _IOC_SIZE(cmd));
  1209. return -EFAULT;
  1210. }
  1211. switch (cmd) {
  1212. case GYROSCOPE_IOCTL_INIT:
  1213. mpu6050_init_client(client, false);
  1214. break;
  1215. case GYROSCOPE_IOCTL_SMT_DATA:
  1216. data = (void __user *)arg;
  1217. if (data == NULL) {
  1218. err = -EINVAL;
  1219. break;
  1220. }
  1221. SMTdata = kzalloc(sizeof(*SMTdata) * 800, GFP_KERNEL);
  1222. if (SMTdata == NULL) {
  1223. err = -ENOMEM;
  1224. break;
  1225. }
  1226. memset(SMTdata, 0, sizeof(*SMTdata) * 800);
  1227. MPU6050_SMTReadSensorData(client, SMTdata, 800);
  1228. GYRO_LOG("gyroscope read data from kernel OK: SMTdata[0]:%d, copied packet:%zd!\n",
  1229. SMTdata[0], ((SMTdata[0] * MPU6050_AXES_NUM + 2) * sizeof(s16) + 1));
  1230. smtRes = MPU6050_PROCESS_SMT_DATA(client, SMTdata);
  1231. GYRO_LOG("ioctl smtRes: %d!\n", smtRes);
  1232. copy_cnt = copy_to_user(data, &smtRes, sizeof(smtRes));
  1233. kfree(SMTdata);
  1234. if (copy_cnt) {
  1235. err = -EFAULT;
  1236. GYRO_ERR("copy gyro data to user failed!\n");
  1237. }
  1238. GYRO_LOG("copy gyro data to user OK: %d!\n", copy_cnt);
  1239. break;
  1240. case GYROSCOPE_IOCTL_READ_SENSORDATA:
  1241. data = (void __user *)arg;
  1242. if (data == NULL) {
  1243. err = -EINVAL;
  1244. break;
  1245. }
  1246. MPU6050_ReadGyroData(client, strbuf, MPU6050_BUFSIZE);
  1247. if (copy_to_user(data, strbuf, sizeof(strbuf))) {
  1248. err = -EFAULT;
  1249. break;
  1250. }
  1251. break;
  1252. case GYROSCOPE_IOCTL_SET_CALI:
  1253. data = (void __user *)arg;
  1254. if (data == NULL) {
  1255. err = -EINVAL;
  1256. break;
  1257. }
  1258. if (copy_from_user(&sensor_data, data, sizeof(sensor_data))) {
  1259. err = -EFAULT;
  1260. break;
  1261. }
  1262. else {
  1263. cali[MPU6050_AXIS_X] = sensor_data.x * MPU6050_DEFAULT_LSB / MPU6050_FS_MAX_LSB;
  1264. cali[MPU6050_AXIS_Y] = sensor_data.y * MPU6050_DEFAULT_LSB / MPU6050_FS_MAX_LSB;
  1265. cali[MPU6050_AXIS_Z] = sensor_data.z * MPU6050_DEFAULT_LSB / MPU6050_FS_MAX_LSB;
  1266. GYRO_LOG("gyro set cali:[%5d %5d %5d]\n",
  1267. cali[MPU6050_AXIS_X], cali[MPU6050_AXIS_Y], cali[MPU6050_AXIS_Z]);
  1268. err = MPU6050_WriteCalibration(client, cali);
  1269. }
  1270. break;
  1271. case GYROSCOPE_IOCTL_CLR_CALI:
  1272. err = MPU6050_ResetCalibration(client);
  1273. break;
  1274. case GYROSCOPE_IOCTL_GET_CALI:
  1275. data = (void __user *)arg;
  1276. if (data == NULL) {
  1277. err = -EINVAL;
  1278. break;
  1279. }
  1280. err = MPU6050_ReadCalibration(client, cali);
  1281. if (err)
  1282. break;
  1283. sensor_data.x = cali[MPU6050_AXIS_X] * MPU6050_FS_MAX_LSB / MPU6050_DEFAULT_LSB;
  1284. sensor_data.y = cali[MPU6050_AXIS_Y] * MPU6050_FS_MAX_LSB / MPU6050_DEFAULT_LSB;
  1285. sensor_data.z = cali[MPU6050_AXIS_Z] * MPU6050_FS_MAX_LSB / MPU6050_DEFAULT_LSB;
  1286. if (copy_to_user(data, &sensor_data, sizeof(sensor_data))) {
  1287. err = -EFAULT;
  1288. break;
  1289. }
  1290. break;
  1291. #if INV_GYRO_AUTO_CALI == 1
  1292. case GYROSCOPE_IOCTL_READ_SENSORDATA_RAW:
  1293. data = (void __user *)arg;
  1294. if (data == NULL) {
  1295. err = -EINVAL;
  1296. break;
  1297. }
  1298. MPU6050_ReadGyroDataRaw(client, strbuf, MPU6050_BUFSIZE);
  1299. if (copy_to_user(data, strbuf, sizeof(strbuf))) {
  1300. err = -EFAULT;
  1301. break;
  1302. }
  1303. break;
  1304. case GYROSCOPE_IOCTL_READ_TEMPERATURE:
  1305. data = (void __user *)arg;
  1306. if (data == NULL) {
  1307. err = -EINVAL;
  1308. break;
  1309. }
  1310. MPU6050_ReadTemperature(client, strbuf, MPU6050_BUFSIZE);
  1311. if (copy_to_user(data, strbuf, sizeof(strbuf))) {
  1312. err = -EFAULT;
  1313. break;
  1314. }
  1315. break;
  1316. case GYROSCOPE_IOCTL_GET_POWER_STATUS:
  1317. data = (void __user *)arg;
  1318. if (data == NULL) {
  1319. err = -EINVAL;
  1320. break;
  1321. }
  1322. MPU6050_ReadPowerStatus(client, strbuf, MPU6050_BUFSIZE);
  1323. if (copy_to_user(data, strbuf, sizeof(strbuf))) {
  1324. err = -EFAULT;
  1325. break;
  1326. }
  1327. break;
  1328. #endif
  1329. default:
  1330. GYRO_ERR("unknown IOCTL: 0x%08x\n", cmd);
  1331. err = -ENOIOCTLCMD;
  1332. break;
  1333. }
  1334. return err;
  1335. }
  1336. #ifdef CONFIG_COMPAT
  1337. static long mpu6050_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  1338. {
  1339. long ret;
  1340. void __user *arg32 = compat_ptr(arg);
  1341. if (!file->f_op || !file->f_op->unlocked_ioctl)
  1342. return -ENOTTY;
  1343. /* printk("akm8963_compat_ioctl arg: 0x%lx, arg32: 0x%p\n",arg, arg32); */
  1344. switch (cmd) {
  1345. case COMPAT_GYROSCOPE_IOCTL_INIT:
  1346. /* printk("akm8963_compat_ioctl COMPAT_ECS_IOCTL_WRITE\n"); */
  1347. if (arg32 == NULL)
  1348. {
  1349. GYRO_ERR("invalid argument.");
  1350. return -EINVAL;
  1351. }
  1352. ret = file->f_op->unlocked_ioctl(file, GYROSCOPE_IOCTL_INIT,
  1353. (unsigned long)arg32);
  1354. if (ret) {
  1355. GYRO_ERR("GYROSCOPE_IOCTL_INIT unlocked_ioctl failed.");
  1356. return ret;
  1357. }
  1358. break;
  1359. case COMPAT_GYROSCOPE_IOCTL_SET_CALI:
  1360. if (arg32 == NULL)
  1361. {
  1362. GYRO_ERR("invalid argument.");
  1363. return -EINVAL;
  1364. }
  1365. ret = file->f_op->unlocked_ioctl(file, GYROSCOPE_IOCTL_SET_CALI,
  1366. (unsigned long)arg32);
  1367. if (ret) {
  1368. GYRO_ERR("GYROSCOPE_IOCTL_SET_CALI unlocked_ioctl failed.");
  1369. return ret;
  1370. }
  1371. break;
  1372. case COMPAT_GYROSCOPE_IOCTL_CLR_CALI:
  1373. if (arg32 == NULL)
  1374. {
  1375. GYRO_ERR("invalid argument.");
  1376. return -EINVAL;
  1377. }
  1378. ret = file->f_op->unlocked_ioctl(file, GYROSCOPE_IOCTL_CLR_CALI,
  1379. (unsigned long)arg32);
  1380. if (ret) {
  1381. GYRO_ERR("GYROSCOPE_IOCTL_CLR_CALI unlocked_ioctl failed.");
  1382. return ret;
  1383. }
  1384. break;
  1385. case COMPAT_GYROSCOPE_IOCTL_GET_CALI:
  1386. if (arg32 == NULL)
  1387. {
  1388. GYRO_ERR("invalid argument.");
  1389. return -EINVAL;
  1390. }
  1391. ret = file->f_op->unlocked_ioctl(file, GYROSCOPE_IOCTL_GET_CALI,
  1392. (unsigned long)arg32);
  1393. if (ret) {
  1394. GYRO_ERR("GYROSCOPE_IOCTL_GET_CALI unlocked_ioctl failed.");
  1395. return ret;
  1396. }
  1397. break;
  1398. case COMPAT_GYROSCOPE_IOCTL_READ_SENSORDATA:
  1399. if (arg32 == NULL)
  1400. {
  1401. GYRO_ERR("invalid argument.");
  1402. return -EINVAL;
  1403. }
  1404. ret = file->f_op->unlocked_ioctl(file, GYROSCOPE_IOCTL_READ_SENSORDATA,
  1405. (unsigned long)arg32);
  1406. if (ret) {
  1407. GYRO_ERR("GYROSCOPE_IOCTL_READ_SENSORDATA unlocked_ioctl failed.");
  1408. return ret;
  1409. }
  1410. break;
  1411. default:
  1412. pr_debug(KERN_ERR "%s not supported = 0x%04x", __func__, cmd);
  1413. return -ENOIOCTLCMD;
  1414. break;
  1415. }
  1416. return 0;
  1417. }
  1418. #endif
  1419. /*----------------------------------------------------------------------------*/
  1420. static const struct file_operations mpu6050_fops = {
  1421. .open = mpu6050_open,
  1422. .release = mpu6050_release,
  1423. .unlocked_ioctl = mpu6050_unlocked_ioctl,
  1424. #ifdef CONFIG_COMPAT
  1425. .compat_ioctl = mpu6050_compat_ioctl,
  1426. #endif
  1427. };
  1428. /*----------------------------------------------------------------------------*/
  1429. static struct miscdevice mpu6050_device = {
  1430. .minor = MISC_DYNAMIC_MINOR,
  1431. .name = "gyroscope",
  1432. .fops = &mpu6050_fops,
  1433. };
  1434. /*----------------------------------------------------------------------------*/
  1435. #ifndef CONFIG_HAS_EARLYSUSPEND
  1436. /*----------------------------------------------------------------------------*/
  1437. static int mpu6050_suspend(struct i2c_client *client, pm_message_t msg)
  1438. {
  1439. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1440. int err = 0;
  1441. GYRO_FUN();
  1442. if (msg.event == PM_EVENT_SUSPEND) {
  1443. if (obj == NULL) {
  1444. GYRO_ERR("null pointer!!\n");
  1445. return -EINVAL;
  1446. }
  1447. atomic_set(&obj->suspend, 1);
  1448. err = MPU6050_SetPowerMode(client, false);
  1449. if (err <= 0)
  1450. return err;
  1451. #if INV_GYRO_AUTO_CALI == 1
  1452. inv_gyro_power_state = sensor_power;
  1453. /* inv_gyro_power_state = 0; */
  1454. /* put this in where gyro power is changed, waking up mpu daemon */
  1455. sysfs_notify(&inv_daemon_device->kobj, NULL, "inv_gyro_power_state");
  1456. #endif
  1457. }
  1458. return err;
  1459. }
  1460. /*----------------------------------------------------------------------------*/
  1461. static int mpu6050_resume(struct i2c_client *client)
  1462. {
  1463. struct mpu6050_i2c_data *obj = i2c_get_clientdata(client);
  1464. int err;
  1465. GYRO_FUN();
  1466. if (obj == NULL) {
  1467. GYRO_ERR("null pointer!!\n");
  1468. return -EINVAL;
  1469. }
  1470. MPU6050_power(obj->hw, 1);
  1471. err = mpu6050_init_client(client, false);
  1472. if (err) {
  1473. GYRO_ERR("initialize client fail!!\n");
  1474. return err;
  1475. }
  1476. atomic_set(&obj->suspend, 0);
  1477. return 0;
  1478. }
  1479. /*----------------------------------------------------------------------------*/
  1480. #else /*CONFIG_HAS_EARLY_SUSPEND is defined */
  1481. /*----------------------------------------------------------------------------*/
  1482. static void mpu6050_early_suspend(struct early_suspend *h)
  1483. {
  1484. struct mpu6050_i2c_data *obj = container_of(h, struct mpu6050_i2c_data, early_drv);
  1485. int err;
  1486. /* u8 databuf[2]; */
  1487. GYRO_FUN();
  1488. if (obj == NULL) {
  1489. GYRO_ERR("null pointer!!\n");
  1490. return;
  1491. }
  1492. atomic_set(&obj->suspend, 1);
  1493. err = MPU6050_SetPowerMode(obj->client, false);
  1494. if (err) {
  1495. GYRO_ERR("write power control fail!!\n");
  1496. return;
  1497. }
  1498. sensor_power = false;
  1499. MPU6050_power(obj->hw, 0);
  1500. #if INV_GYRO_AUTO_CALI == 1
  1501. inv_gyro_power_state = sensor_power;
  1502. /* inv_gyro_power_state = 0; */
  1503. /* put this in where gyro power is changed, waking up mpu daemon */
  1504. sysfs_notify(&inv_daemon_device->kobj, NULL, "inv_gyro_power_state");
  1505. #endif
  1506. }
  1507. /*----------------------------------------------------------------------------*/
  1508. static void mpu6050_late_resume(struct early_suspend *h)
  1509. {
  1510. struct mpu6050_i2c_data *obj = container_of(h, struct mpu6050_i2c_data, early_drv);
  1511. int err;
  1512. GYRO_FUN();
  1513. if (obj == NULL) {
  1514. GYRO_ERR("null pointer!!\n");
  1515. return;
  1516. }
  1517. MPU6050_power(obj->hw, 1);
  1518. err = mpu6050_init_client(obj->client, false);
  1519. if (err) {
  1520. GYRO_ERR("initialize client fail! err code %d!\n", err);
  1521. return;
  1522. }
  1523. atomic_set(&obj->suspend, 0);
  1524. }
  1525. /*----------------------------------------------------------------------------*/
  1526. #endif /*CONFIG_HAS_EARLYSUSPEND */
  1527. /*----------------------------------------------------------------------------*/
  1528. static int mpu6050_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
  1529. {
  1530. strcpy(info->type, MPU6050_DEV_NAME);
  1531. return 0;
  1532. }
  1533. /* if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL */
  1534. static int mpu6050_open_report_data(int open)
  1535. {
  1536. /* should queuq work to report event if is_report_input_direct=true */
  1537. return 0;
  1538. }
  1539. /* if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL */
  1540. static int mpu6050_enable_nodata(int en)
  1541. {
  1542. int res = 0;
  1543. int retry = 0;
  1544. bool power = false;
  1545. if (1 == en)
  1546. {
  1547. power = true;
  1548. }
  1549. if (0 == en)
  1550. {
  1551. power = false;
  1552. }
  1553. for (retry = 0; retry < 3; retry++) {
  1554. res = MPU6050_SetPowerMode(obj_i2c_data->client, power);
  1555. if (res == 0)
  1556. {
  1557. GYRO_LOG("MPU6050_SetPowerMode done\n");
  1558. break;
  1559. }
  1560. GYRO_LOG("MPU6050_SetPowerMode fail\n");
  1561. }
  1562. if (res != MPU6050_SUCCESS)
  1563. {
  1564. GYRO_LOG("MPU6050_SetPowerMode fail!\n");
  1565. return -1;
  1566. }
  1567. GYRO_LOG("mpu6050_enable_nodata OK!\n");
  1568. return 0;
  1569. }
  1570. static int mpu6050_set_delay(u64 ns)
  1571. {
  1572. return 0;
  1573. }
  1574. static int mpu6050_get_data(int *x , int *y, int *z, int *status)
  1575. {
  1576. char buff[MPU6050_BUFSIZE];
  1577. MPU6050_ReadGyroData(obj_i2c_data->client, buff, MPU6050_BUFSIZE);
  1578. sscanf(buff, "%x %x %x", x, y, z);
  1579. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1580. return 0;
  1581. }
  1582. /*----------------------------------------------------------------------------*/
  1583. static int mpu6050_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  1584. {
  1585. struct i2c_client *new_client;
  1586. struct mpu6050_i2c_data *obj;
  1587. int err = 0;
  1588. struct gyro_control_path ctl = {0};
  1589. struct gyro_data_path data = {0};
  1590. GYRO_FUN();
  1591. obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  1592. if (!(obj)) {
  1593. err = -ENOMEM;
  1594. goto exit;
  1595. }
  1596. memset(obj, 0, sizeof(struct mpu6050_i2c_data));
  1597. obj->hw = hw;
  1598. err = hwmsen_get_convert(obj->hw->direction, &obj->cvt);
  1599. if (err) {
  1600. GYRO_ERR("invalid direction: %d\n", obj->hw->direction);
  1601. goto exit;
  1602. }
  1603. GYRO_LOG("gyro_default_i2c_addr: %x\n", client->addr);
  1604. #ifdef MPU6050_ACCESS_BY_GSE_I2C
  1605. obj->hw->addr = MPU6050_I2C_SLAVE_ADDR; /* mtk i2c not allow to probe two same address */
  1606. #endif
  1607. GYRO_LOG("gyro_custom_i2c_addr: %x\n", obj->hw->addr);
  1608. if (0 != obj->hw->addr) {
  1609. client->addr = obj->hw->addr >> 1;
  1610. GYRO_LOG("gyro_use_i2c_addr: %x\n", client->addr);
  1611. }
  1612. obj_i2c_data = obj;
  1613. obj->client = client;
  1614. new_client = obj->client;
  1615. i2c_set_clientdata(new_client, obj);
  1616. atomic_set(&obj->trace, 0);
  1617. atomic_set(&obj->suspend, 0);
  1618. mpu6050_i2c_client = new_client;
  1619. err = mpu6050_init_client(new_client, false);
  1620. if (err)
  1621. goto exit_init_failed;
  1622. err = misc_register(&mpu6050_device);
  1623. if (err) {
  1624. GYRO_ERR("mpu6050_device misc register failed!\n");
  1625. goto exit_misc_device_register_failed;
  1626. }
  1627. ctl.is_use_common_factory = false;
  1628. err = mpu6050_create_attr(&(mpu6050_init_info.platform_diver_addr->driver));
  1629. if (err) {
  1630. GYRO_ERR("mpu6050 create attribute err = %d\n", err);
  1631. goto exit_create_attr_failed;
  1632. }
  1633. ctl.open_report_data = mpu6050_open_report_data;
  1634. ctl.enable_nodata = mpu6050_enable_nodata;
  1635. ctl.set_delay = mpu6050_set_delay;
  1636. ctl.is_report_input_direct = false;
  1637. ctl.is_support_batch = obj->hw->is_batch_supported;
  1638. err = gyro_register_control_path(&ctl);
  1639. if (err)
  1640. {
  1641. GYRO_ERR("register gyro control path err\n");
  1642. goto exit_kfree;
  1643. }
  1644. data.get_data = mpu6050_get_data;
  1645. data.vender_div = DEGREE_TO_RAD;
  1646. err = gyro_register_data_path(&data);
  1647. if (err)
  1648. {
  1649. GYRO_ERR("gyro_register_data_path fail = %d\n", err);
  1650. goto exit_kfree;
  1651. }
  1652. #ifdef CONFIG_HAS_EARLYSUSPEND
  1653. obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 2,
  1654. obj->early_drv.suspend = mpu6050_early_suspend,
  1655. obj->early_drv.resume = mpu6050_late_resume, register_early_suspend(&obj->early_drv);
  1656. #endif
  1657. #if INV_GYRO_AUTO_CALI == 1
  1658. mutex_init(&obj->temperature_mutex);
  1659. mutex_init(&obj->raw_data_mutex);
  1660. {
  1661. int i;
  1662. int result;
  1663. /* create a class to avoid event drop by uevent_ops->filter function (dev_uevent_filter()) */
  1664. inv_daemon_class = class_create(THIS_MODULE, INV_DAEMON_CLASS_NAME);
  1665. if (IS_ERR(inv_daemon_class)) {
  1666. GYRO_ERR("cannot create inv daemon class, %s\n", INV_DAEMON_CLASS_NAME);
  1667. goto exit_class_create_failed;
  1668. }
  1669. #if 0
  1670. inv_daemon_device = device_create(inv_daemon_class, NULL,
  1671. MKDEV(MISC_MAJOR, MISC_DYNAMIC_MINOR), NULL,
  1672. INV_DAEMON_DEVICE_NAME);
  1673. if (IS_ERR(inv_daemon_device)) {
  1674. GYRO_ERR("cannot create inv daemon device, %s\n", INV_DAEMON_DEVICE_NAME);
  1675. goto exit_inv_device_create_failed;
  1676. }
  1677. #endif
  1678. inv_daemon_device = kzalloc(sizeof(struct device), GFP_KERNEL);
  1679. if (!inv_daemon_device) {
  1680. GYRO_ERR("cannot allocate inv daemon device, %s\n", INV_DAEMON_DEVICE_NAME);
  1681. goto exit_device_register_failed;
  1682. }
  1683. inv_daemon_device->init_name = INV_DAEMON_DEVICE_NAME;
  1684. inv_daemon_device->class = inv_daemon_class;
  1685. inv_daemon_device->release = (void (*)(struct device *))kfree;
  1686. result = device_register(inv_daemon_device);
  1687. if (result) {
  1688. GYRO_ERR("cannot register inv daemon device, %s\n", INV_DAEMON_DEVICE_NAME);
  1689. goto exit_device_register_failed;
  1690. }
  1691. result = 0;
  1692. for (i = 0; i < ARRAY_SIZE(inv_daemon_dev_attributes); i++) {
  1693. result =
  1694. device_create_file(inv_daemon_device, inv_daemon_dev_attributes[i]);
  1695. if (result)
  1696. break;
  1697. }
  1698. if (result) {
  1699. while (--i >= 0)
  1700. device_remove_file(inv_daemon_device, inv_daemon_dev_attributes[i]);
  1701. GYRO_ERR("cannot create inv daemon dev attr.\n");
  1702. goto exit_create_file_failed;
  1703. }
  1704. }
  1705. #endif
  1706. mpu6050_init_flag = 0;
  1707. GYRO_LOG("%s: OK\n", __func__);
  1708. return 0;
  1709. #if INV_GYRO_AUTO_CALI == 1
  1710. exit_create_file_failed:
  1711. device_unregister(inv_daemon_device);
  1712. exit_device_register_failed:
  1713. class_destroy(inv_daemon_class);
  1714. exit_class_create_failed:
  1715. hwmsen_detach(ID_GYROSCOPE);
  1716. #endif
  1717. exit_create_attr_failed:
  1718. misc_deregister(&mpu6050_device);
  1719. exit_misc_device_register_failed:
  1720. exit_init_failed:
  1721. /* i2c_detach_client(new_client); */
  1722. exit_kfree:
  1723. kfree(obj);
  1724. exit:
  1725. mpu6050_init_flag = -1;
  1726. GYRO_ERR("%s: err = %d\n", __func__, err);
  1727. return err;
  1728. }
  1729. /*----------------------------------------------------------------------------*/
  1730. static int mpu6050_i2c_remove(struct i2c_client *client)
  1731. {
  1732. int err = 0;
  1733. #if INV_GYRO_AUTO_CALI == 1
  1734. {
  1735. int i;
  1736. for (i = 0; i < ARRAY_SIZE(inv_daemon_dev_attributes); i++)
  1737. device_remove_file(inv_daemon_device, inv_daemon_dev_attributes[i]);
  1738. device_unregister(inv_daemon_device);
  1739. class_destroy(inv_daemon_class);
  1740. }
  1741. #endif
  1742. err = mpu6050_delete_attr(&(mpu6050_init_info.platform_diver_addr->driver));
  1743. if (err)
  1744. GYRO_ERR("mpu6050_delete_attr fail: %d\n", err);
  1745. err = misc_deregister(&mpu6050_device);
  1746. if (err)
  1747. GYRO_ERR("misc_deregister fail: %d\n", err);
  1748. err = hwmsen_detach(ID_GYROSCOPE);
  1749. if (err)
  1750. GYRO_ERR("hwmsen_detach fail: %d\n", err);
  1751. mpu6050_i2c_client = NULL;
  1752. i2c_unregister_device(client);
  1753. kfree(i2c_get_clientdata(client));
  1754. return 0;
  1755. }
  1756. /*----------------------------------------------------------------------------*/
  1757. /*----------------------------------------------------------------------------*/
  1758. static int mpu6050_remove(void)
  1759. {
  1760. GYRO_FUN();
  1761. MPU6050_power(hw, 0);
  1762. i2c_del_driver(&mpu6050_i2c_driver);
  1763. return 0;
  1764. }
  1765. /*----------------------------------------------------------------------------*/
  1766. static int mpu6050_local_init(struct platform_device *pdev)
  1767. {
  1768. MPU6050_power(hw, 1);
  1769. if (i2c_add_driver(&mpu6050_i2c_driver))
  1770. {
  1771. GYRO_ERR("add driver error\n");
  1772. return -1;
  1773. }
  1774. if (-1 == mpu6050_init_flag)
  1775. {
  1776. return -1;
  1777. }
  1778. return 0;
  1779. }
  1780. /*----------------------------------------------------------------------------*/
  1781. static int __init mpu6050_init(void)
  1782. {
  1783. const char *name = "mediatek,mpu6050gy";
  1784. hw = get_gyro_dts_func(name, hw);
  1785. if (!hw)
  1786. GYRO_ERR("get dts info fail\n");
  1787. gyro_driver_add(&mpu6050_init_info);
  1788. return 0;
  1789. }
  1790. /*----------------------------------------------------------------------------*/
  1791. static void __exit mpu6050_exit(void)
  1792. {
  1793. GYRO_FUN();
  1794. }
  1795. /*----------------------------------------------------------------------------*/
  1796. module_init(mpu6050_init);
  1797. module_exit(mpu6050_exit);
  1798. /*----------------------------------------------------------------------------*/
  1799. MODULE_LICENSE("GPL");
  1800. MODULE_DESCRIPTION("MPU6050 gyroscope driver");
  1801. MODULE_AUTHOR("Yucong.Xiong@mediatek.com");