akm09912.c 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167
  1. /*
  2. * Copyright(C)2014 MediaTek Inc.
  3. * Modification based on code covered by the below mentioned copyright
  4. * and/or permission notice(S).
  5. */
  6. /* akm09912.c - akm09912 compass driver
  7. *
  8. *
  9. * This software is licensed under the terms of the GNU General Public
  10. * License version 2, as published by the Free Software Foundation, and
  11. * may be copied, distributed, and modified under those terms.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. */
  19. #include <cust_mag.h>
  20. #include "akm09912.h"
  21. #include "mag.h"
  22. /*----------------------------------------------------------------------------*/
  23. #define DEBUG 0
  24. #define AKM09912_DEV_NAME "akm09912"
  25. #define DRIVER_VERSION "1.0.1"
  26. /*----------------------------------------------------------------------------*/
  27. #define AKM09912_DEBUG 1
  28. #define AKM09912_RETRY_COUNT 10
  29. #define AKM09912_DEFAULT_DELAY 100
  30. #if AKM09912_DEBUG
  31. #define MAGN_TAG "[Msensor] "
  32. #define MAGN_FUN(f) pr_debug(MAGN_TAG"%s\n", __func__)
  33. #define MAGN_ERR(fmt, args...) pr_err(MAGN_TAG"%s %d : "fmt, __func__, __LINE__, ##args)
  34. #define MAGN_LOG(fmt, args...) pr_debug(MAGN_TAG fmt, ##args)
  35. #else
  36. #define MAGN_TAG
  37. #define MAGN_FUN(f) do {} while (0)
  38. #define MAGN_ERR(fmt, args...) do {} while (0)
  39. #define MAGN_LOG(fmt, args...) do {} while (0)
  40. #endif
  41. /* Addresses to scan -- protected by sense_data_mutex */
  42. static char sense_data[SENSOR_DATA_SIZE];
  43. static struct mutex sense_data_mutex;
  44. static int sensor_data[CALIBRATION_DATA_SIZE];
  45. static struct mutex sensor_data_mutex;
  46. static DECLARE_WAIT_QUEUE_HEAD(open_wq);
  47. static short akmd_delay = AKM09912_DEFAULT_DELAY;
  48. static atomic_t open_flag = ATOMIC_INIT(0);
  49. static atomic_t m_flag = ATOMIC_INIT(0);
  50. static atomic_t o_flag = ATOMIC_INIT(0);
  51. static int factory_mode;
  52. static int akm09912_init_flag;
  53. static struct i2c_client *this_client;
  54. /*----------------------------------------------------------------------------*/
  55. static const struct i2c_device_id akm09912_i2c_id[] = { {AKM09912_DEV_NAME, 0}, {} };
  56. /* Maintain cust info here */
  57. struct mag_hw mag_cust;
  58. static struct mag_hw *hw = &mag_cust;
  59. /* For driver get cust info */
  60. struct mag_hw *get_cust_mag(void)
  61. {
  62. return &mag_cust;
  63. }
  64. #define MTK_I2C_FUNCTION
  65. /*----------------------------------------------------------------------------*/
  66. static int akm09912_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
  67. static int akm09912_i2c_remove(struct i2c_client *client);
  68. static int akm09912_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
  69. static int akm09912_suspend(struct i2c_client *client, pm_message_t msg);
  70. static int akm09912_resume(struct i2c_client *client);
  71. static int akm09912_local_init(void);
  72. static int akm09912_remove(void);
  73. static struct mag_init_info akm09912_init_info = {
  74. .name = "akm09912",
  75. .init = akm09912_local_init,
  76. .uninit = akm09912_remove,
  77. };
  78. /*----------------------------------------------------------------------------*/
  79. enum {
  80. AMK_FUN_DEBUG = 0x01,
  81. AMK_DATA_DEBUG = 0X02,
  82. AMK_HWM_DEBUG = 0X04,
  83. AMK_CTR_DEBUG = 0X08,
  84. AMK_I2C_DEBUG = 0x10,
  85. } AMK_TRC;
  86. /*----------------------------------------------------------------------------*/
  87. struct akm09912_i2c_data {
  88. struct i2c_client *client;
  89. struct mag_hw *hw;
  90. atomic_t layout;
  91. atomic_t trace;
  92. struct hwmsen_convert cvt;
  93. };
  94. /*----------------------------------------------------------------------------*/
  95. #ifdef CONFIG_OF
  96. static const struct of_device_id mag_of_match[] = {
  97. {.compatible = "mediatek,msensor"},
  98. {},
  99. };
  100. #endif
  101. static struct i2c_driver akm09912_i2c_driver = {
  102. .driver = {
  103. .name = AKM09912_DEV_NAME,
  104. #ifdef CONFIG_OF
  105. .of_match_table = mag_of_match,
  106. #endif
  107. },
  108. .probe = akm09912_i2c_probe,
  109. .remove = akm09912_i2c_remove,
  110. .detect = akm09912_i2c_detect,
  111. .suspend = akm09912_suspend,
  112. .resume = akm09912_resume,
  113. .id_table = akm09912_i2c_id,
  114. };
  115. /*----------------------------------------------------------------------------*/
  116. static atomic_t dev_open_count;
  117. /*----------------------------------------------------------------------------*/
  118. static DEFINE_MUTEX(akm09912_i2c_mutex);
  119. static int mag_i2c_read_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
  120. {
  121. int err = 0;
  122. u8 beg = addr;
  123. struct i2c_msg msgs[2] = { {0}, {0} };
  124. mutex_lock(&akm09912_i2c_mutex);
  125. msgs[0].addr = client->addr;
  126. msgs[0].flags = 0;
  127. msgs[0].len = 1;
  128. msgs[0].buf = &beg;
  129. msgs[1].addr = client->addr;
  130. msgs[1].flags = I2C_M_RD;
  131. msgs[1].len = len;
  132. msgs[1].buf = data;
  133. if (!client) {
  134. mutex_unlock(&akm09912_i2c_mutex);
  135. return -EINVAL;
  136. } else if (len > C_I2C_FIFO_SIZE) {
  137. mutex_unlock(&akm09912_i2c_mutex);
  138. MAGN_ERR(" length %d exceeds %d\n", len, C_I2C_FIFO_SIZE);
  139. return -EINVAL;
  140. }
  141. err = i2c_transfer(client->adapter, msgs, sizeof(msgs) / sizeof(msgs[0]));
  142. if (err != 2) {
  143. MAGN_ERR("i2c_transfer error: (%d %p %d) %d\n", addr, data, len, err);
  144. err = -EIO;
  145. } else {
  146. err = 0;
  147. }
  148. mutex_unlock(&akm09912_i2c_mutex);
  149. return err;
  150. }
  151. static int mag_i2c_write_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
  152. { /*because address also occupies one byte, the maximum length for write is 7 bytes */
  153. int err = 0, idx = 0, num = 0;
  154. char buf[C_I2C_FIFO_SIZE];
  155. err = 0;
  156. mutex_lock(&akm09912_i2c_mutex);
  157. if (!client) {
  158. mutex_unlock(&akm09912_i2c_mutex);
  159. return -EINVAL;
  160. } else if (len >= C_I2C_FIFO_SIZE) {
  161. mutex_unlock(&akm09912_i2c_mutex);
  162. MAGN_ERR(" length %d exceeds %d\n", len, C_I2C_FIFO_SIZE);
  163. return -EINVAL;
  164. }
  165. num = 0;
  166. buf[num++] = addr;
  167. for (idx = 0; idx < len; idx++)
  168. buf[num++] = data[idx];
  169. err = i2c_master_send(client, buf, num);
  170. if (err < 0) {
  171. mutex_unlock(&akm09912_i2c_mutex);
  172. MAGN_ERR("send command error!!\n");
  173. return -EFAULT;
  174. }
  175. mutex_unlock(&akm09912_i2c_mutex);
  176. return err;
  177. }
  178. static void akm09912_power(struct mag_hw *hw, unsigned int on)
  179. {
  180. }
  181. static long AKI2C_RxData(char *rxData, int length)
  182. {
  183. #ifdef MTK_I2C_FUNCTION
  184. struct i2c_client *client = this_client;
  185. int res = 0;
  186. char addr = rxData[0];
  187. if ((rxData == NULL) || (length < 1))
  188. return -EINVAL;
  189. res = mag_i2c_read_block(client, addr, rxData, length);
  190. if (res < 0)
  191. return -1;
  192. return 0;
  193. #else
  194. uint8_t loop_i = 0;
  195. #if DEBUG
  196. int i = 0;
  197. struct i2c_client *client = this_client;
  198. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  199. char addr = rxData[0];
  200. #endif
  201. /* Caller should check parameter validity. */
  202. if ((rxData == NULL) || (length < 1))
  203. return -EINVAL;
  204. mutex_lock(&akm09912_i2c_mutex);
  205. for (loop_i = 0; loop_i < AKM09912_RETRY_COUNT; loop_i++) {
  206. this_client->addr = this_client->addr & I2C_MASK_FLAG;
  207. this_client->addr = this_client->addr | I2C_WR_FLAG;
  208. if (i2c_master_send(this_client, (const char *)rxData, ((length << 0X08) | 0X01)))
  209. break;
  210. mdelay(10);
  211. }
  212. if (loop_i >= AKM09912_RETRY_COUNT) {
  213. mutex_unlock(&akm09912_i2c_mutex);
  214. MAG_ERR("%s retry over %d\n", __func__, AKM09912_RETRY_COUNT);
  215. return -EIO;
  216. }
  217. mutex_unlock(&akm09912_i2c_mutex);
  218. #if DEBUG
  219. if (atomic_read(&data->trace) & AMK_I2C_DEBUG) {
  220. MAGN_LOG("RxData: len=%02x, addr=%02x\n data=", length, addr);
  221. for (i = 0; i < length; i++)
  222. MAGN_LOG(" %02x", rxData[i]);
  223. MAGN_LOG("\n");
  224. }
  225. #endif
  226. return 0;
  227. #endif
  228. }
  229. static long AKI2C_TxData(char *txData, int length)
  230. {
  231. #ifdef MTK_I2C_FUNCTION
  232. struct i2c_client *client = this_client;
  233. int res = 0;
  234. char addr = txData[0];
  235. u8 *buff = &txData[1];
  236. if ((txData == NULL) || (length < 2))
  237. return -EINVAL;
  238. res = mag_i2c_write_block(client, addr, buff, (length - 1));
  239. if (res < 0)
  240. return -1;
  241. return 0;
  242. #else
  243. uint8_t loop_i = 0;
  244. #if DEBUG
  245. int i = 0;
  246. struct i2c_client *client = this_client;
  247. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  248. #endif
  249. /* Caller should check parameter validity. */
  250. if ((txData == NULL) || (length < 2))
  251. return -EINVAL;
  252. mutex_lock(&akm09912_i2c_mutex);
  253. this_client->addr = this_client->addr & I2C_MASK_FLAG;
  254. for (loop_i = 0; loop_i < AKM09912_RETRY_COUNT; loop_i++) {
  255. if (i2c_master_send(this_client, (const char *)txData, length) > 0)
  256. break;
  257. mdelay(10);
  258. }
  259. if (loop_i >= AKM09912_RETRY_COUNT) {
  260. mutex_unlock(&akm09912_i2c_mutex);
  261. MAG_ERR("%s retry over %d\n", __func__, AKM09912_RETRY_COUNT);
  262. return -EIO;
  263. }
  264. mutex_unlock(&akm09912_i2c_mutex);
  265. #if DEBUG
  266. if (atomic_read(&data->trace) & AMK_I2C_DEBUG) {
  267. MAGN_LOG("TxData: len=%02x, addr=%02x\n data=", length, txData[0]);
  268. for (i = 0; i < (length - 1); i++)
  269. MAGN_LOG(" %02x", txData[i + 1]);
  270. MAGN_LOG("\n");
  271. }
  272. #endif
  273. return 0;
  274. #endif
  275. }
  276. static long AKECS_SetMode_SngMeasure(void)
  277. {
  278. char buffer[2];
  279. #ifdef AKM_Device_AK8963
  280. buffer[0] = AK8963_REG_CNTL1;
  281. buffer[1] = AK8963_MODE_SNG_MEASURE;
  282. #else
  283. /* Set measure mode */
  284. buffer[0] = AK09912_REG_CNTL2;
  285. buffer[1] = AK09912_MODE_SNG_MEASURE;
  286. #endif
  287. /* Set data */
  288. return AKI2C_TxData(buffer, 2);
  289. }
  290. static long AKECS_SetMode_SelfTest(void)
  291. {
  292. char buffer[2];
  293. #ifdef AKM_Device_AK8963
  294. buffer[0] = AK8963_REG_CNTL1;
  295. buffer[1] = AK8963_MODE_SELF_TEST;
  296. #else
  297. /* Set measure mode */
  298. buffer[0] = AK09912_REG_CNTL2;
  299. buffer[1] = AK09912_MODE_SELF_TEST;
  300. /* Set data */
  301. #endif
  302. return AKI2C_TxData(buffer, 2);
  303. }
  304. static long AKECS_SetMode_FUSEAccess(void)
  305. {
  306. char buffer[2];
  307. #ifdef AKM_Device_AK8963
  308. buffer[0] = AK8963_REG_CNTL1;
  309. buffer[1] = AK8963_MODE_FUSE_ACCESS;
  310. #else
  311. /* Set measure mode */
  312. buffer[0] = AK09912_REG_CNTL2;
  313. buffer[1] = AK09912_MODE_FUSE_ACCESS;
  314. /* Set data */
  315. #endif
  316. return AKI2C_TxData(buffer, 2);
  317. }
  318. static int AKECS_SetMode_PowerDown(void)
  319. {
  320. char buffer[2];
  321. #ifdef AKM_Device_AK8963
  322. buffer[0] = AK8963_REG_CNTL1;
  323. buffer[1] = AK8963_MODE_POWERDOWN;
  324. #else
  325. /* Set powerdown mode */
  326. buffer[0] = AK09912_REG_CNTL2;
  327. buffer[1] = AK09912_MODE_POWERDOWN;
  328. /* Set data */
  329. #endif
  330. return AKI2C_TxData(buffer, 2);
  331. }
  332. static long AKECS_Reset(int hard)
  333. {
  334. unsigned char buffer[2];
  335. long err = 0;
  336. if (hard != 0) {
  337. udelay(5);
  338. } else {
  339. /* Set measure mode */
  340. #ifdef AKM_Device_AK8963
  341. buffer[0] = AK8963_REG_CNTL2;
  342. buffer[1] = 0x01;
  343. #else
  344. buffer[0] = AK09912_REG_CNTL3;
  345. buffer[1] = 0x01;
  346. #endif
  347. err = AKI2C_TxData(buffer, 2);
  348. if (err < 0)
  349. MAGN_LOG("%s: Can not set SRST bit.", __func__);
  350. else
  351. MAGN_LOG("Soft reset is done.");
  352. }
  353. /* Device will be accessible 300 us after */
  354. udelay(300);
  355. return err;
  356. }
  357. static long AKECS_SetMode(char mode)
  358. {
  359. long ret = 0;
  360. switch (mode & 0x1F) {
  361. case AK09912_MODE_SNG_MEASURE:
  362. ret = AKECS_SetMode_SngMeasure();
  363. break;
  364. case AK09912_MODE_SELF_TEST:
  365. case AK8963_MODE_SELF_TEST:
  366. ret = AKECS_SetMode_SelfTest();
  367. break;
  368. case AK09912_MODE_FUSE_ACCESS:
  369. case AK8963_MODE_FUSE_ACCESS:
  370. ret = AKECS_SetMode_FUSEAccess();
  371. break;
  372. case AK09912_MODE_POWERDOWN:
  373. ret = AKECS_SetMode_PowerDown();
  374. break;
  375. default:
  376. MAGN_LOG("%s: Unknown mode(%d)", __func__, mode);
  377. return -EINVAL;
  378. }
  379. /* wait at least 100us after changing mode */
  380. udelay(100);
  381. return ret;
  382. }
  383. static int AKECS_CheckDevice(void)
  384. {
  385. char buffer[2];
  386. int ret = 0;
  387. MAGN_LOG(" AKM check device id");
  388. /* Set measure mode */
  389. #ifdef AKM_Device_AK8963
  390. buffer[0] = AK8963_REG_WIA;
  391. #else
  392. buffer[0] = AK09912_REG_WIA1;
  393. #endif
  394. /* Read data */
  395. ret = AKI2C_RxData(buffer, 1);
  396. MAGN_LOG(" AKM check device id = %x", buffer[0]);
  397. MAGN_LOG("ret = %d", ret);
  398. if (ret < 0)
  399. return ret;
  400. /* Check read data */
  401. if (buffer[0] != 0x48)
  402. return -ENXIO;
  403. return 0;
  404. }
  405. static void AKECS_SaveData(int *buf)
  406. {
  407. #if DEBUG
  408. struct i2c_client *client = this_client;
  409. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  410. #endif
  411. mutex_lock(&sensor_data_mutex);
  412. memcpy(sensor_data, buf, sizeof(sensor_data));
  413. mutex_unlock(&sensor_data_mutex);
  414. #if DEBUG
  415. if (atomic_read(&data->trace) & AMK_HWM_DEBUG) {
  416. MAGN_LOG("Get daemon data: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d!\n",
  417. sensor_data[0], sensor_data[1], sensor_data[2], sensor_data[3],
  418. sensor_data[4], sensor_data[5], sensor_data[6], sensor_data[7],
  419. sensor_data[8], sensor_data[9], sensor_data[10], sensor_data[11]);
  420. MAGN_LOG("Get daemon data: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d!\n",
  421. sensor_data[12], sensor_data[13], sensor_data[14], sensor_data[15],
  422. sensor_data[16], sensor_data[17], sensor_data[18], sensor_data[19],
  423. sensor_data[20], sensor_data[21], sensor_data[22], sensor_data[23],
  424. sensor_data[24], sensor_data[25]);
  425. }
  426. #endif
  427. }
  428. static long AKECS_GetData(char *rbuf, int size)
  429. {
  430. char temp = 0;
  431. int loop_i = 0, ret = 0;
  432. #if DEBUG
  433. struct i2c_client *client = this_client;
  434. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  435. #endif
  436. if (size < SENSOR_DATA_SIZE) {
  437. MAG_ERR("buff size is too small %d!\n", size);
  438. return -1;
  439. }
  440. memset(rbuf, 0, SENSOR_DATA_SIZE);
  441. #ifdef AKM_Device_AK8963
  442. rbuf[0] = AK8963_REG_ST1;
  443. #else
  444. rbuf[0] = AK09912_REG_ST1;
  445. #endif
  446. for (loop_i = 0; loop_i < AKM09912_RETRY_COUNT; loop_i++) {
  447. ret = AKI2C_RxData(rbuf, 1);
  448. if (ret) {
  449. MAG_ERR("read ST1 resigster failed!\n");
  450. return -1;
  451. }
  452. if ((rbuf[0] & 0x01) == 0x01)
  453. break;
  454. usleep_range(1000, 2000);
  455. #ifdef AKM_Device_AK8963
  456. rbuf[0] = AK8963_REG_ST1;
  457. #else
  458. rbuf[0] = AK09912_REG_ST1;
  459. #endif
  460. }
  461. if (loop_i >= AKM09912_RETRY_COUNT) {
  462. MAG_ERR("Data read retry larger the max count!\n");
  463. if (0 == factory_mode)
  464. return -1;
  465. }
  466. temp = rbuf[0];
  467. #ifdef AKM_Device_AK8963
  468. rbuf[1] = AK8963_REG_HXL;
  469. ret = AKI2C_RxData(&rbuf[1], SENSOR_DATA_SIZE - 2);
  470. #else
  471. rbuf[1] = AK09912_REG_HXL;
  472. ret = AKI2C_RxData(&rbuf[1], SENSOR_DATA_SIZE - 1);
  473. #endif
  474. if (ret < 0) {
  475. MAG_ERR("AKM8975 akm8975_work_func: I2C failed\n");
  476. return -1;
  477. }
  478. rbuf[0] = temp;
  479. #ifdef AKM_Device_AK8963
  480. rbuf[8] = rbuf[7];
  481. rbuf[7] = 0;
  482. #endif
  483. mutex_lock(&sense_data_mutex);
  484. memcpy(sense_data, rbuf, sizeof(sense_data));
  485. mutex_unlock(&sense_data_mutex);
  486. #if DEBUG
  487. if (atomic_read(&data->trace) & AMK_DATA_DEBUG) {
  488. MAGN_LOG("Get device data: %d, %d, %d, %d , %d, %d, %d, %d!\n",
  489. sense_data[0], sense_data[1], sense_data[2], sense_data[3],
  490. sense_data[4], sense_data[5], sense_data[6], sense_data[7]);
  491. }
  492. #endif
  493. return 0;
  494. }
  495. static int AKECS_GetRawData(char *rbuf, int size)
  496. {
  497. char strbuf[SENSOR_DATA_SIZE];
  498. s16 data[3];
  499. if ((atomic_read(&open_flag) == 0) || (factory_mode == 1)) {
  500. AKECS_SetMode_SngMeasure();
  501. usleep_range(4000, 5000);
  502. }
  503. AKECS_GetData(strbuf, SENSOR_DATA_SIZE);
  504. data[0] = (s16) (strbuf[1] | (strbuf[2] << 8));
  505. data[1] = (s16) (strbuf[3] | (strbuf[4] << 8));
  506. data[2] = (s16) (strbuf[5] | (strbuf[6] << 8));
  507. sprintf(rbuf, "%x %x %x", data[0], data[1], data[2]);
  508. return 0;
  509. }
  510. static int AKECS_GetOpenStatus(void)
  511. {
  512. wait_event_interruptible(open_wq, (atomic_read(&open_flag) != 0));
  513. return atomic_read(&open_flag);
  514. }
  515. static int AKECS_GetCloseStatus(void)
  516. {
  517. wait_event_interruptible(open_wq, (atomic_read(&open_flag) <= 0));
  518. return atomic_read(&open_flag);
  519. }
  520. /*----------------------------------------------------------------------------*/
  521. static int akm09912_ReadChipInfo(char *buf, int bufsize)
  522. {
  523. if ((!buf) || (bufsize <= AKM09912_BUFSIZE - 1))
  524. return -1;
  525. if (!this_client) {
  526. *buf = 0;
  527. return -2;
  528. }
  529. sprintf(buf, "akm09912 Chip");
  530. return 0;
  531. }
  532. /*----------------------------shipment test------------------------------------------------*/
  533. /*!
  534. @return If @a testdata is in the range of between @a lolimit and @a hilimit,
  535. the return value is 1, otherwise -1.
  536. @param[in] testno A pointer to a text string.
  537. @param[in] testname A pointer to a text string.
  538. @param[in] testdata A data to be tested.
  539. @param[in] lolimit The maximum allowable value of @a testdata.
  540. @param[in] hilimit The minimum allowable value of @a testdata.
  541. @param[in,out] pf_total
  542. */
  543. int
  544. TEST_DATA(const char testno[],
  545. const char testname[], const int testdata, const int lolimit, const int hilimit, int *pf_total)
  546. {
  547. int pf = 0;
  548. if ((testno == NULL) && (strncmp(testname, "START", 5) == 0)) {
  549. MAGN_LOG("--------------------------------------------------------------------\n");
  550. MAGN_LOG(" Test No. Test Name Fail Test Data [ Low High]\n");
  551. MAGN_LOG("--------------------------------------------------------------------\n");
  552. pf = 1;
  553. } else if ((testno == NULL) && (strncmp(testname, "END", 3) == 0)) {
  554. MAGN_LOG("--------------------------------------------------------------------\n");
  555. if (*pf_total == 1)
  556. MAGN_LOG("Factory shipment test was passed.\n\n");
  557. else
  558. MAGN_LOG("Factory shipment test was failed.\n\n");
  559. pf = 1;
  560. } else {
  561. if ((lolimit <= testdata) && (testdata <= hilimit))
  562. pf = 1;
  563. else
  564. pf = -1;
  565. MAGN_LOG(" %7s %-10s %c %9d [%9d %9d]\n",
  566. testno, testname, ((pf == 1) ? ('.') : ('F')), testdata, lolimit, hilimit);
  567. }
  568. if (*pf_total != 0) {
  569. if ((*pf_total == 1) && (pf == 1))
  570. *pf_total = 1;
  571. else
  572. *pf_total = -1;
  573. }
  574. return pf;
  575. }
  576. int FST_AK8963(void)
  577. {
  578. int pf_total = 0;
  579. char i2cData[16];
  580. int hdata[3];
  581. int asax = 0;
  582. int asay = 0;
  583. int asaz = 0;
  584. pf_total = 1;
  585. AKECS_Reset(0);
  586. usleep_range(1000, 2000);
  587. if (CSPEC_SPI_USE == 1) {
  588. i2cData[0] = AK8963_REG_I2CDIS;
  589. i2cData[1] = 0x1B;
  590. if (AKI2C_TxData(i2cData, 2) < 0) {
  591. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  592. return 0;
  593. }
  594. }
  595. i2cData[0] = AK8963_REG_WIA;
  596. if (AKI2C_RxData(i2cData, 7) < 0) {
  597. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  598. return 0;
  599. }
  600. TEST_DATA(TLIMIT_NO_RST_WIA, TLIMIT_TN_RST_WIA, (int)i2cData[0], TLIMIT_LO_RST_WIA, TLIMIT_HI_RST_WIA,
  601. &pf_total);
  602. TEST_DATA(TLIMIT_NO_RST_INFO, TLIMIT_TN_RST_INFO, (int)i2cData[1], TLIMIT_LO_RST_INFO, TLIMIT_HI_RST_INFO,
  603. &pf_total);
  604. TEST_DATA(TLIMIT_NO_RST_ST1, TLIMIT_TN_RST_ST1, (int)i2cData[2], TLIMIT_LO_RST_ST1, TLIMIT_HI_RST_ST1,
  605. &pf_total);
  606. TEST_DATA(TLIMIT_NO_RST_HXL, TLIMIT_TN_RST_HXL, (int)i2cData[3], TLIMIT_LO_RST_HXL, TLIMIT_HI_RST_HXL,
  607. &pf_total);
  608. TEST_DATA(TLIMIT_NO_RST_HXH, TLIMIT_TN_RST_HXH, (int)i2cData[4], TLIMIT_LO_RST_HXH, TLIMIT_HI_RST_HXH,
  609. &pf_total);
  610. TEST_DATA(TLIMIT_NO_RST_HYL, TLIMIT_TN_RST_HYL, (int)i2cData[5], TLIMIT_LO_RST_HYL, TLIMIT_HI_RST_HYL,
  611. &pf_total);
  612. TEST_DATA(TLIMIT_NO_RST_HYH, TLIMIT_TN_RST_HYH, (int)i2cData[6], TLIMIT_LO_RST_HYH, TLIMIT_HI_RST_HYH,
  613. &pf_total);
  614. i2cData[7] = AK8963_REG_HZL;
  615. if (AKI2C_RxData((i2cData + 7), 6) < 0) {
  616. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  617. return 0;
  618. }
  619. TEST_DATA(TLIMIT_NO_RST_HZL, TLIMIT_TN_RST_HZL, (int)i2cData[7], TLIMIT_LO_RST_HZL, TLIMIT_HI_RST_HZL,
  620. &pf_total);
  621. TEST_DATA(TLIMIT_NO_RST_HZH, TLIMIT_TN_RST_HZH, (int)i2cData[8], TLIMIT_LO_RST_HZH, TLIMIT_HI_RST_HZH,
  622. &pf_total);
  623. TEST_DATA(TLIMIT_NO_RST_ST2, TLIMIT_TN_RST_ST2, (int)i2cData[9], TLIMIT_LO_RST_ST2, TLIMIT_HI_RST_ST2,
  624. &pf_total);
  625. TEST_DATA(TLIMIT_NO_RST_CNTL, TLIMIT_TN_RST_CNTL, (int)i2cData[10], TLIMIT_LO_RST_CNTL, TLIMIT_HI_RST_CNTL,
  626. &pf_total);
  627. TEST_DATA(TLIMIT_NO_RST_ASTC, TLIMIT_TN_RST_ASTC, (int)i2cData[12], TLIMIT_LO_RST_ASTC, TLIMIT_HI_RST_ASTC,
  628. &pf_total);
  629. i2cData[0] = AK8963_REG_I2CDIS;
  630. if (AKI2C_RxData(i2cData, 1) < 0) {
  631. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  632. return 0;
  633. }
  634. if (CSPEC_SPI_USE == 1) {
  635. TEST_DATA(TLIMIT_NO_RST_I2CDIS, TLIMIT_TN_RST_I2CDIS, (int)i2cData[0], TLIMIT_LO_RST_I2CDIS_USESPI,
  636. TLIMIT_HI_RST_I2CDIS_USESPI, &pf_total);
  637. } else {
  638. TEST_DATA(TLIMIT_NO_RST_I2CDIS, TLIMIT_TN_RST_I2CDIS, (int)i2cData[0], TLIMIT_LO_RST_I2CDIS_USEI2C,
  639. TLIMIT_HI_RST_I2CDIS_USEI2C, &pf_total);
  640. }
  641. if (AKECS_SetMode(AK8963_MODE_FUSE_ACCESS) < 0) {
  642. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  643. return 0;
  644. }
  645. i2cData[0] = AK8963_FUSE_ASAX;
  646. if (AKI2C_RxData(i2cData, 3) < 0) {
  647. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  648. return 0;
  649. }
  650. asax = (int)i2cData[0];
  651. asay = (int)i2cData[1];
  652. asaz = (int)i2cData[2];
  653. TEST_DATA(TLIMIT_NO_ASAX, TLIMIT_TN_ASAX, asax, TLIMIT_LO_ASAX, TLIMIT_HI_ASAX, &pf_total);
  654. TEST_DATA(TLIMIT_NO_ASAY, TLIMIT_TN_ASAY, asay, TLIMIT_LO_ASAY, TLIMIT_HI_ASAY, &pf_total);
  655. TEST_DATA(TLIMIT_NO_ASAZ, TLIMIT_TN_ASAZ, asaz, TLIMIT_LO_ASAZ, TLIMIT_HI_ASAZ, &pf_total);
  656. i2cData[0] = AK8963_REG_CNTL1;
  657. if (AKI2C_RxData(i2cData, 1) < 0) {
  658. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  659. return 0;
  660. }
  661. if (AKECS_SetMode(AK8963_MODE_POWERDOWN) < 0) {
  662. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  663. return 0;
  664. }
  665. TEST_DATA(TLIMIT_NO_WR_CNTL, TLIMIT_TN_WR_CNTL, (int)i2cData[0], TLIMIT_LO_WR_CNTL, TLIMIT_HI_WR_CNTL,
  666. &pf_total);
  667. if (AKECS_SetMode(AK8963_MODE_SNG_MEASURE) < 0) {
  668. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  669. return 0;
  670. }
  671. usleep_range(8000, 10000);
  672. if (AKECS_GetData(i2cData, SENSOR_DATA_SIZE) < 0) {
  673. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  674. return 0;
  675. }
  676. hdata[0] = (s16) (i2cData[1] | (i2cData[2] << 8));
  677. hdata[1] = (s16) (i2cData[3] | (i2cData[4] << 8));
  678. hdata[2] = (s16) (i2cData[5] | (i2cData[6] << 8));
  679. hdata[0] <<= 2;
  680. hdata[1] <<= 2;
  681. hdata[2] <<= 2;
  682. TEST_DATA(TLIMIT_NO_SNG_ST1, TLIMIT_TN_SNG_ST1, (int)i2cData[0], TLIMIT_LO_SNG_ST1, TLIMIT_HI_SNG_ST1,
  683. &pf_total);
  684. TEST_DATA(TLIMIT_NO_SNG_HX, TLIMIT_TN_SNG_HX, hdata[0], TLIMIT_LO_SNG_HX, TLIMIT_HI_SNG_HX, &pf_total);
  685. TEST_DATA(TLIMIT_NO_SNG_HY, TLIMIT_TN_SNG_HY, hdata[1], TLIMIT_LO_SNG_HY, TLIMIT_HI_SNG_HY, &pf_total);
  686. TEST_DATA(TLIMIT_NO_SNG_HZ, TLIMIT_TN_SNG_HZ, hdata[2], TLIMIT_LO_SNG_HZ, TLIMIT_HI_SNG_HZ, &pf_total);
  687. TEST_DATA(TLIMIT_NO_SNG_ST2, TLIMIT_TN_SNG_ST2, (int)i2cData[8], TLIMIT_LO_SNG_ST2, TLIMIT_HI_SNG_ST2,
  688. &pf_total);
  689. i2cData[0] = AK8963_REG_ASTC;
  690. i2cData[1] = 0x40;
  691. if (AKI2C_TxData(i2cData, 2) < 0) {
  692. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  693. return 0;
  694. }
  695. if (AKECS_SetMode(AK8963_MODE_SELF_TEST) < 0) {
  696. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  697. return 0;
  698. }
  699. usleep_range(8000, 10000);
  700. if (AKECS_GetData(i2cData, SENSOR_DATA_SIZE) < 0) {
  701. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  702. return 0;
  703. }
  704. TEST_DATA(TLIMIT_NO_SLF_ST1, TLIMIT_TN_SLF_ST1, (int)i2cData[0], TLIMIT_LO_SLF_ST1, TLIMIT_HI_SLF_ST1,
  705. &pf_total);
  706. hdata[0] = (s16) (i2cData[1] | (i2cData[2] << 8));
  707. hdata[1] = (s16) (i2cData[3] | (i2cData[4] << 8));
  708. hdata[2] = (s16) (i2cData[5] | (i2cData[6] << 8));
  709. hdata[0] <<= 2;
  710. hdata[1] <<= 2;
  711. hdata[2] <<= 2;
  712. MAGN_LOG("hdata[0] = %d\n", hdata[0]);
  713. MAGN_LOG("asax = %d\n", asax);
  714. TEST_DATA(TLIMIT_NO_SLF_RVHX,
  715. TLIMIT_TN_SLF_RVHX,
  716. (hdata[0]) * ((asax - 128) / 2 / 128 + 1), TLIMIT_LO_SLF_RVHX, TLIMIT_HI_SLF_RVHX, &pf_total);
  717. TEST_DATA(TLIMIT_NO_SLF_RVHY,
  718. TLIMIT_TN_SLF_RVHY,
  719. (hdata[1]) * ((asay - 128) / 2 / 128 + 1), TLIMIT_LO_SLF_RVHY, TLIMIT_HI_SLF_RVHY, &pf_total);
  720. TEST_DATA(TLIMIT_NO_SLF_RVHZ,
  721. TLIMIT_TN_SLF_RVHZ,
  722. (hdata[2]) * ((asaz - 128) / 2 / 128 + 1), TLIMIT_LO_SLF_RVHZ, TLIMIT_HI_SLF_RVHZ, &pf_total);
  723. TEST_DATA(TLIMIT_NO_SLF_ST2, TLIMIT_TN_SLF_ST2, (int)i2cData[8], TLIMIT_LO_SLF_ST2, TLIMIT_HI_SLF_ST2,
  724. &pf_total);
  725. i2cData[0] = AK8963_REG_ASTC;
  726. i2cData[1] = 0x00;
  727. if (AKI2C_TxData(i2cData, 2) < 0) {
  728. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  729. return 0;
  730. }
  731. MAGN_LOG("pf_total = %d\n", pf_total);
  732. return pf_total;
  733. }
  734. /*!
  735. Execute "Onboard Function Test" (NOT includes "START" and "END" command).
  736. @retval 1 The test is passed successfully.
  737. @retval -1 The test is failed.
  738. @retval 0 The test is aborted by kind of system error.
  739. */
  740. int FST_AK09912(void)
  741. {
  742. int pf_total = 0;
  743. char i2cData[16];
  744. int hdata[3];
  745. int asax = 0;
  746. int asay = 0;
  747. int asaz = 0;
  748. pf_total = 1;
  749. if (AKECS_Reset(0) < 0) {
  750. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  751. return 0;
  752. }
  753. i2cData[0] = AK09912_REG_WIA1;
  754. if (AKI2C_RxData(i2cData, 2) < 0) {
  755. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  756. return 0;
  757. }
  758. TEST_DATA(TLIMIT_NO_RST_WIA1_09912, TLIMIT_TN_RST_WIA1_09912, (int)i2cData[0], TLIMIT_LO_RST_WIA1_09912,
  759. TLIMIT_HI_RST_WIA1_09912, &pf_total);
  760. TEST_DATA(TLIMIT_NO_RST_WIA2_09912, TLIMIT_TN_RST_WIA2_09912, (int)i2cData[1], TLIMIT_LO_RST_WIA2_09912,
  761. TLIMIT_HI_RST_WIA2_09912, &pf_total);
  762. if (AKECS_SetMode(AK09912_MODE_FUSE_ACCESS) < 0) {
  763. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  764. return 0;
  765. }
  766. i2cData[0] = AK09912_REG_CNTL2;
  767. if (AKI2C_RxData(i2cData, 1) < 0) {
  768. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  769. return 0;
  770. }
  771. TEST_DATA(TLIMIT_NO_WR_CNTL2_09912, TLIMIT_TN_WR_CNTL2_09912, (int)i2cData[0], TLIMIT_LO_WR_CNTL2_09912,
  772. TLIMIT_HI_WR_CNTL2_09912, &pf_total);
  773. i2cData[0] = AK09912_FUSE_ASAX;
  774. if (AKI2C_RxData(i2cData, 3) < 0) {
  775. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  776. return 0;
  777. }
  778. asax = (int)i2cData[0];
  779. asay = (int)i2cData[1];
  780. asaz = (int)i2cData[2];
  781. TEST_DATA(TLIMIT_NO_ASAX_09912, TLIMIT_TN_ASAX_09912, asax, TLIMIT_LO_ASAX_09912, TLIMIT_HI_ASAX_09912,
  782. &pf_total);
  783. TEST_DATA(TLIMIT_NO_ASAY_09912, TLIMIT_TN_ASAY_09912, asay, TLIMIT_LO_ASAY_09912, TLIMIT_HI_ASAY_09912,
  784. &pf_total);
  785. TEST_DATA(TLIMIT_NO_ASAZ_09912, TLIMIT_TN_ASAZ_09912, asaz, TLIMIT_LO_ASAZ_09912, TLIMIT_HI_ASAZ_09912,
  786. &pf_total);
  787. if (AKECS_SetMode(AK09912_MODE_POWERDOWN) < 0) {
  788. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  789. return 0;
  790. }
  791. i2cData[0] = AK09912_REG_CNTL1;
  792. if (AKI2C_RxData(i2cData, 1) < 0) {
  793. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  794. return 0;
  795. }
  796. if (AKECS_SetMode(AK09912_MODE_SNG_MEASURE) < 0) {
  797. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  798. return 0;
  799. }
  800. if (AKECS_GetData(i2cData, SENSOR_DATA_SIZE) < 0) {
  801. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  802. return 0;
  803. }
  804. hdata[0] = (s16) (i2cData[1] | (i2cData[2] << 8));
  805. hdata[1] = (s16) (i2cData[3] | (i2cData[4] << 8));
  806. hdata[2] = (s16) (i2cData[5] | (i2cData[6] << 8));
  807. i2cData[0] &= 0x7F;
  808. TEST_DATA(TLIMIT_NO_SNG_ST1_09912, TLIMIT_TN_SNG_ST1_09912, (int)i2cData[0], TLIMIT_LO_SNG_ST1_09912,
  809. TLIMIT_HI_SNG_ST1_09912, &pf_total);
  810. TEST_DATA(TLIMIT_NO_SNG_HX_09912, TLIMIT_TN_SNG_HX_09912, hdata[0], TLIMIT_LO_SNG_HX_09912,
  811. TLIMIT_HI_SNG_HX_09912, &pf_total);
  812. TEST_DATA(TLIMIT_NO_SNG_HY_09912, TLIMIT_TN_SNG_HY_09912, hdata[1], TLIMIT_LO_SNG_HY_09912,
  813. TLIMIT_HI_SNG_HY_09912, &pf_total);
  814. TEST_DATA(TLIMIT_NO_SNG_HZ_09912, TLIMIT_TN_SNG_HZ_09912, hdata[2], TLIMIT_LO_SNG_HZ_09912,
  815. TLIMIT_HI_SNG_HZ_09912, &pf_total);
  816. TEST_DATA(TLIMIT_NO_SNG_ST2_09912, TLIMIT_TN_SNG_ST2_09912, (int)i2cData[8], TLIMIT_LO_SNG_ST2_09912,
  817. TLIMIT_HI_SNG_ST2_09912, &pf_total);
  818. if (AKECS_SetMode(AK09912_MODE_SELF_TEST) < 0) {
  819. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  820. return 0;
  821. }
  822. if (AKECS_GetData(i2cData, SENSOR_DATA_SIZE) < 0) {
  823. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  824. return 0;
  825. }
  826. i2cData[0] &= 0x7F;
  827. TEST_DATA(TLIMIT_NO_SLF_ST1_09912, TLIMIT_TN_SLF_ST1_09912, (int)i2cData[0], TLIMIT_LO_SLF_ST1_09912,
  828. TLIMIT_HI_SLF_ST1_09912, &pf_total);
  829. hdata[0] = (s16) (i2cData[1] | (i2cData[2] << 8));
  830. hdata[1] = (s16) (i2cData[3] | (i2cData[4] << 8));
  831. hdata[2] = (s16) (i2cData[5] | (i2cData[6] << 8));
  832. TEST_DATA(TLIMIT_NO_SLF_RVHX_09912,
  833. TLIMIT_TN_SLF_RVHX_09912,
  834. (hdata[0]) * ((asax - 128) / 256 + 1), TLIMIT_LO_SLF_RVHX_09912, TLIMIT_HI_SLF_RVHX_09912, &pf_total);
  835. TEST_DATA(TLIMIT_NO_SLF_RVHY_09912,
  836. TLIMIT_TN_SLF_RVHY_09912,
  837. (hdata[1]) * ((asay - 128) / 256 + 1), TLIMIT_LO_SLF_RVHY_09912, TLIMIT_HI_SLF_RVHY_09912, &pf_total);
  838. TEST_DATA(TLIMIT_NO_SLF_RVHZ_09912,
  839. TLIMIT_TN_SLF_RVHZ_09912,
  840. (hdata[2]) * ((asaz - 128) / 256 + 1), TLIMIT_LO_SLF_RVHZ_09912, TLIMIT_HI_SLF_RVHZ_09912, &pf_total);
  841. TEST_DATA(TLIMIT_NO_SLF_ST2_09912,
  842. TLIMIT_TN_SLF_ST2_09912,
  843. (int)i2cData[8], TLIMIT_LO_SLF_ST2_09912, TLIMIT_HI_SLF_ST2_09912, &pf_total);
  844. return pf_total;
  845. }
  846. /*!
  847. Execute "Onboard Function Test" (includes "START" and "END" command).
  848. @retval 1 The test is passed successfully.
  849. @retval -1 The test is failed.
  850. @retval 0 The test is aborted by kind of system error.
  851. */
  852. int FctShipmntTestProcess_Body(void)
  853. {
  854. int pf_total = 1;
  855. TEST_DATA(NULL, "START", 0, 0, 0, &pf_total);
  856. #ifdef AKM_Device_AK8963
  857. pf_total = FST_AK8963();
  858. #else
  859. pf_total = FST_AK09912();
  860. #endif
  861. TEST_DATA(NULL, "END", 0, 0, 0, &pf_total);
  862. return pf_total;
  863. }
  864. static ssize_t store_shipment_test(struct device_driver *ddri, const char *buf, size_t count)
  865. {
  866. return count;
  867. }
  868. static ssize_t show_shipment_test(struct device_driver *ddri, char *buf)
  869. {
  870. char result[10];
  871. int res = 0;
  872. res = FctShipmntTestProcess_Body();
  873. if (1 == res) {
  874. MAGN_LOG("shipment_test pass\n");
  875. strcpy(result, "y");
  876. } else if (-1 == res) {
  877. MAGN_LOG("shipment_test fail\n");
  878. strcpy(result, "n");
  879. } else {
  880. MAGN_LOG("shipment_test NaN\n");
  881. strcpy(result, "NaN");
  882. }
  883. return sprintf(buf, "%s\n", result);
  884. }
  885. static ssize_t show_daemon_name(struct device_driver *ddri, char *buf)
  886. {
  887. char strbuf[AKM09912_BUFSIZE];
  888. sprintf(strbuf, "akmd09912");
  889. return sprintf(buf, "%s", strbuf);
  890. }
  891. static ssize_t show_chipinfo_value(struct device_driver *ddri, char *buf)
  892. {
  893. char strbuf[AKM09912_BUFSIZE];
  894. akm09912_ReadChipInfo(strbuf, AKM09912_BUFSIZE);
  895. return sprintf(buf, "%s\n", strbuf);
  896. }
  897. /*----------------------------------------------------------------------------*/
  898. static ssize_t show_sensordata_value(struct device_driver *ddri, char *buf)
  899. {
  900. char sensordata[SENSOR_DATA_SIZE];
  901. char strbuf[AKM09912_BUFSIZE];
  902. if (atomic_read(&open_flag) == 0) {
  903. AKECS_SetMode_SngMeasure();
  904. usleep_range(8000, 10000);
  905. AKECS_GetData(sensordata, SENSOR_DATA_SIZE);
  906. } else {
  907. mutex_lock(&sense_data_mutex);
  908. memcpy(sensordata, sense_data, sizeof(sensordata));
  909. mutex_unlock(&sense_data_mutex);
  910. }
  911. sprintf(strbuf, "%d %d %d %d %d %d %d %d %d\n", sensordata[0], sensordata[1], sensordata[2],
  912. sensordata[3], sensordata[4], sensordata[5], sensordata[6], sensordata[7], sensordata[8]);
  913. return sprintf(buf, "%s\n", strbuf);
  914. }
  915. /*----------------------------------------------------------------------------*/
  916. static ssize_t show_posturedata_value(struct device_driver *ddri, char *buf)
  917. {
  918. short tmp[3];
  919. char strbuf[AKM09912_BUFSIZE];
  920. tmp[0] = sensor_data[13] * CONVERT_O / CONVERT_O_DIV;
  921. tmp[1] = sensor_data[14] * CONVERT_O / CONVERT_O_DIV;
  922. tmp[2] = sensor_data[15] * CONVERT_O / CONVERT_O_DIV;
  923. sprintf(strbuf, "%d, %d, %d\n", tmp[0], tmp[1], tmp[2]);
  924. return sprintf(buf, "%s\n", strbuf);
  925. }
  926. /*----------------------------------------------------------------------------*/
  927. static ssize_t show_layout_value(struct device_driver *ddri, char *buf)
  928. {
  929. struct i2c_client *client = this_client;
  930. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  931. return sprintf(buf, "(%d, %d)\n[%+2d %+2d %+2d]\n[%+2d %+2d %+2d]\n",
  932. data->hw->direction, atomic_read(&data->layout), data->cvt.sign[0], data->cvt.sign[1],
  933. data->cvt.sign[2], data->cvt.map[0], data->cvt.map[1], data->cvt.map[2]);
  934. }
  935. /*----------------------------------------------------------------------------*/
  936. static ssize_t store_layout_value(struct device_driver *ddri, const char *buf, size_t count)
  937. {
  938. struct i2c_client *client = this_client;
  939. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  940. int layout = 0;
  941. int err = 0;
  942. err = kstrtoint(buf, 10, &layout);
  943. if (err == 0) {
  944. atomic_set(&data->layout, layout);
  945. if (!hwmsen_get_convert(layout, &data->cvt)) {
  946. MAG_ERR("HWMSEN_GET_CONVERT function error!\r\n");
  947. } else if (!hwmsen_get_convert(data->hw->direction, &data->cvt)) {
  948. MAG_ERR("invalid layout: %d, restore to %d\n", layout, data->hw->direction);
  949. } else {
  950. MAG_ERR("invalid layout: (%d, %d)\n", layout, data->hw->direction);
  951. hwmsen_get_convert(0, &data->cvt);
  952. }
  953. } else {
  954. MAG_ERR("invalid format = '%s'\n", buf);
  955. }
  956. return count;
  957. }
  958. /*----------------------------------------------------------------------------*/
  959. static ssize_t show_status_value(struct device_driver *ddri, char *buf)
  960. {
  961. struct i2c_client *client = this_client;
  962. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  963. ssize_t len = 0;
  964. if (data->hw)
  965. len += snprintf(buf + len, PAGE_SIZE - len, "CUST: %d %d (%d %d)\n",
  966. data->hw->i2c_num, data->hw->direction, data->hw->power_id, data->hw->power_vol);
  967. else
  968. len += snprintf(buf + len, PAGE_SIZE - len, "CUST: NULL\n");
  969. len += snprintf(buf + len, PAGE_SIZE - len, "OPEN: %d\n", atomic_read(&dev_open_count));
  970. return len;
  971. }
  972. /*----------------------------------------------------------------------------*/
  973. static ssize_t show_trace_value(struct device_driver *ddri, char *buf)
  974. {
  975. ssize_t res = 0;
  976. struct akm09912_i2c_data *obj = i2c_get_clientdata(this_client);
  977. if (NULL == obj) {
  978. MAG_ERR("akm09912_i2c_data is null!!\n");
  979. return 0;
  980. }
  981. res = snprintf(buf, PAGE_SIZE, "0x%04X\n", atomic_read(&obj->trace));
  982. return res;
  983. }
  984. /*----------------------------------------------------------------------------*/
  985. static ssize_t store_trace_value(struct device_driver *ddri, const char *buf, size_t count)
  986. {
  987. struct akm09912_i2c_data *obj = i2c_get_clientdata(this_client);
  988. int trace = 0;
  989. if (NULL == obj) {
  990. MAG_ERR("akm09912_i2c_data is null!!\n");
  991. return 0;
  992. }
  993. if (1 == sscanf(buf, "0x%x", &trace))
  994. atomic_set(&obj->trace, trace);
  995. else
  996. MAG_ERR("invalid content: '%s', length = %zu\n", buf, count);
  997. return count;
  998. }
  999. static ssize_t show_chip_orientation(struct device_driver *ddri, char *buf)
  1000. {
  1001. ssize_t _tLength = 0;
  1002. struct mag_hw *_ptAccelHw = hw;
  1003. MAGN_LOG("[%s] default direction: %d\n", __func__, _ptAccelHw->direction);
  1004. _tLength = snprintf(buf, PAGE_SIZE, "default direction = %d\n", _ptAccelHw->direction);
  1005. return _tLength;
  1006. }
  1007. static ssize_t store_chip_orientation(struct device_driver *ddri, const char *buf, size_t tCount)
  1008. {
  1009. int _nDirection = 0, err = 0;
  1010. struct akm09912_i2c_data *_pt_i2c_obj = i2c_get_clientdata(this_client);
  1011. if (NULL == _pt_i2c_obj)
  1012. return 0;
  1013. err = kstrtoint(buf, 10, &_nDirection);
  1014. if (err == 0) {
  1015. if (hwmsen_get_convert(_nDirection, &_pt_i2c_obj->cvt))
  1016. MAG_ERR("ERR: fail to set direction\n");
  1017. }
  1018. MAGN_LOG("[%s] set direction: %d\n", __func__, _nDirection);
  1019. return tCount;
  1020. }
  1021. static ssize_t show_power_status(struct device_driver *ddri, char *buf)
  1022. {
  1023. ssize_t res = 0;
  1024. u8 uData = AK09912_REG_CNTL2;
  1025. struct akm09912_i2c_data *obj = i2c_get_clientdata(this_client);
  1026. if (obj == NULL) {
  1027. MAG_ERR("i2c_data obj is null!!\n");
  1028. return 0;
  1029. }
  1030. AKI2C_RxData(&uData, 1);
  1031. res = snprintf(buf, PAGE_SIZE, "0x%04X\n", uData);
  1032. return res;
  1033. }
  1034. static ssize_t show_regiter_map(struct device_driver *ddri, char *buf)
  1035. {
  1036. u8 _bIndex = 0;
  1037. u8 _baRegMap[] = {
  1038. 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  1039. 0x30, 0x31, 0x32, 0x33, 0x60, 0x61, 0x62
  1040. };
  1041. ssize_t _tLength = 0;
  1042. char tmp[2] = { 0 };
  1043. for (_bIndex = 0; _bIndex < 20; _bIndex++) {
  1044. tmp[0] = _baRegMap[_bIndex];
  1045. AKI2C_RxData(tmp, 1);
  1046. _tLength +=
  1047. snprintf((buf + _tLength), (PAGE_SIZE - _tLength), "Reg[0x%02X]: 0x%02X\n", _baRegMap[_bIndex],
  1048. tmp[0]);
  1049. }
  1050. return _tLength;
  1051. }
  1052. /*----------------------------------------------------------------------------*/
  1053. static DRIVER_ATTR(daemon, S_IRUGO, show_daemon_name, NULL);
  1054. static DRIVER_ATTR(shipmenttest, S_IRUGO | S_IWUSR, show_shipment_test, store_shipment_test);
  1055. static DRIVER_ATTR(chipinfo, S_IRUGO, show_chipinfo_value, NULL);
  1056. static DRIVER_ATTR(sensordata, S_IRUGO, show_sensordata_value, NULL);
  1057. static DRIVER_ATTR(posturedata, S_IRUGO, show_posturedata_value, NULL);
  1058. static DRIVER_ATTR(layout, S_IRUGO | S_IWUSR, show_layout_value, store_layout_value);
  1059. static DRIVER_ATTR(status, S_IRUGO, show_status_value, NULL);
  1060. static DRIVER_ATTR(trace, S_IRUGO | S_IWUSR, show_trace_value, store_trace_value);
  1061. static DRIVER_ATTR(orientation, S_IWUSR | S_IRUGO, show_chip_orientation, store_chip_orientation);
  1062. static DRIVER_ATTR(power, S_IRUGO, show_power_status, NULL);
  1063. static DRIVER_ATTR(regmap, S_IRUGO, show_regiter_map, NULL);
  1064. /*----------------------------------------------------------------------------*/
  1065. static struct driver_attribute *akm09912_attr_list[] = {
  1066. &driver_attr_daemon,
  1067. &driver_attr_shipmenttest,
  1068. &driver_attr_chipinfo,
  1069. &driver_attr_sensordata,
  1070. &driver_attr_posturedata,
  1071. &driver_attr_layout,
  1072. &driver_attr_status,
  1073. &driver_attr_trace,
  1074. &driver_attr_orientation,
  1075. &driver_attr_power,
  1076. &driver_attr_regmap,
  1077. };
  1078. /*----------------------------------------------------------------------------*/
  1079. static int akm09912_create_attr(struct device_driver *driver)
  1080. {
  1081. int idx = 0, err = 0;
  1082. int num = (int)(sizeof(akm09912_attr_list) / sizeof(akm09912_attr_list[0]));
  1083. if (driver == NULL)
  1084. return -EINVAL;
  1085. for (idx = 0; idx < num; idx++) {
  1086. err = driver_create_file(driver, akm09912_attr_list[idx]);
  1087. if (err) {
  1088. MAG_ERR("driver_create_file (%s) = %d\n", akm09912_attr_list[idx]->attr.name, err);
  1089. break;
  1090. }
  1091. }
  1092. return err;
  1093. }
  1094. /*----------------------------------------------------------------------------*/
  1095. static int akm09912_delete_attr(struct device_driver *driver)
  1096. {
  1097. int idx = 0, err = 0;
  1098. int num = (int)(sizeof(akm09912_attr_list) / sizeof(akm09912_attr_list[0]));
  1099. if (driver == NULL)
  1100. return -EINVAL;
  1101. for (idx = 0; idx < num; idx++)
  1102. driver_remove_file(driver, akm09912_attr_list[idx]);
  1103. return err;
  1104. }
  1105. /*----------------------------------------------------------------------------*/
  1106. static int akm09912_open(struct inode *inode, struct file *file)
  1107. {
  1108. struct akm09912_i2c_data *obj = i2c_get_clientdata(this_client);
  1109. int ret = -1;
  1110. if (atomic_read(&obj->trace) & AMK_CTR_DEBUG)
  1111. MAGN_LOG("Open device node:akm09912\n");
  1112. ret = nonseekable_open(inode, file);
  1113. return ret;
  1114. }
  1115. /*----------------------------------------------------------------------------*/
  1116. static int akm09912_release(struct inode *inode, struct file *file)
  1117. {
  1118. struct akm09912_i2c_data *obj = i2c_get_clientdata(this_client);
  1119. atomic_dec(&dev_open_count);
  1120. if (atomic_read(&obj->trace) & AMK_CTR_DEBUG)
  1121. MAGN_LOG("Release device node:akm09912\n");
  1122. return 0;
  1123. }
  1124. /*----------------------------------------------------------------------------*/
  1125. static long akm09912_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  1126. {
  1127. void __user *argp = (void __user *)arg;
  1128. /* NOTE: In this function the size of "char" should be 1-byte. */
  1129. char sData[SENSOR_DATA_SIZE]; /* for GETDATA */
  1130. char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */
  1131. char buff[AKM09912_BUFSIZE]; /* for chip information */
  1132. char mode = 0; /* for SET_MODE */
  1133. int value[26]; /* for SET_YPR */
  1134. int64_t delay[3]; /* for GET_DELAY */
  1135. int status = 0; /* for OPEN/CLOSE_STATUS */
  1136. long ret = -1; /* Return value. */
  1137. int layout = 0;
  1138. struct i2c_client *client = this_client;
  1139. struct akm09912_i2c_data *data = i2c_get_clientdata(client);
  1140. struct hwm_sensor_data *osensor_data;
  1141. uint32_t enable = 0;
  1142. /* These two buffers are initialized at start up.
  1143. After that, the value is not changed */
  1144. unsigned char sense_info[AKM_SENSOR_INFO_SIZE];
  1145. unsigned char sense_conf[AKM_SENSOR_CONF_SIZE];
  1146. switch (cmd) {
  1147. case ECS_IOCTL_WRITE:
  1148. if (argp == NULL) {
  1149. MAGN_LOG("invalid argument.");
  1150. return -EINVAL;
  1151. }
  1152. if (copy_from_user(rwbuf, argp, sizeof(rwbuf))) {
  1153. MAGN_LOG("copy_from_user failed.");
  1154. return -EFAULT;
  1155. }
  1156. if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE - 1))) {
  1157. MAGN_LOG("invalid argument.");
  1158. return -EINVAL;
  1159. }
  1160. ret = AKI2C_TxData(&rwbuf[1], rwbuf[0]);
  1161. if (ret < 0)
  1162. return ret;
  1163. break;
  1164. case ECS_IOCTL_RESET:
  1165. ret = AKECS_Reset(0);
  1166. if (ret < 0)
  1167. return ret;
  1168. break;
  1169. case ECS_IOCTL_READ:
  1170. if (argp == NULL) {
  1171. MAGN_LOG("invalid argument.");
  1172. return -EINVAL;
  1173. }
  1174. if (copy_from_user(rwbuf, argp, sizeof(rwbuf))) {
  1175. MAGN_LOG("copy_from_user failed.");
  1176. return -EFAULT;
  1177. }
  1178. if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE - 1))) {
  1179. MAGN_LOG("invalid argument.");
  1180. return -EINVAL;
  1181. }
  1182. ret = AKI2C_RxData(&rwbuf[1], rwbuf[0]);
  1183. if (ret < 0)
  1184. return ret;
  1185. if (copy_to_user(argp, rwbuf, rwbuf[0] + 1)) {
  1186. MAGN_LOG("copy_to_user failed.");
  1187. return -EFAULT;
  1188. }
  1189. break;
  1190. case ECS_IOCTL_GET_INFO:
  1191. #ifdef AKM_Device_AK8963
  1192. sense_info[0] = AK8963_REG_WIA;
  1193. #else
  1194. sense_info[0] = AK09912_REG_WIA1;
  1195. #endif
  1196. ret = AKI2C_RxData(sense_info, AKM_SENSOR_INFO_SIZE);
  1197. if (ret < 0)
  1198. return ret;
  1199. if (copy_to_user(argp, sense_info, AKM_SENSOR_INFO_SIZE)) {
  1200. MAGN_LOG("copy_to_user failed.");
  1201. return -EFAULT;
  1202. }
  1203. break;
  1204. case ECS_IOCTL_GET_CONF:
  1205. /* Set FUSE access mode */
  1206. #ifdef AKM_Device_AK8963
  1207. ret = AKECS_SetMode(AK8963_MODE_FUSE_ACCESS);
  1208. #else
  1209. ret = AKECS_SetMode(AK09912_MODE_FUSE_ACCESS);
  1210. #endif
  1211. if (ret < 0)
  1212. return ret;
  1213. #ifdef AKM_Device_AK8963
  1214. sense_conf[0] = AK8963_FUSE_ASAX;
  1215. #else
  1216. sense_conf[0] = AK09912_FUSE_ASAX;
  1217. #endif
  1218. ret = AKI2C_RxData(sense_conf, AKM_SENSOR_CONF_SIZE);
  1219. if (ret < 0)
  1220. return ret;
  1221. if (copy_to_user(argp, sense_conf, AKM_SENSOR_CONF_SIZE)) {
  1222. MAGN_LOG("copy_to_user failed.");
  1223. return -EFAULT;
  1224. }
  1225. #ifdef AKM_Device_AK8963
  1226. ret = AKECS_SetMode(AK8963_MODE_POWERDOWN);
  1227. #else
  1228. ret = AKECS_SetMode(AK09912_MODE_POWERDOWN);
  1229. #endif
  1230. if (ret < 0)
  1231. return ret;
  1232. break;
  1233. case ECS_IOCTL_SET_MODE:
  1234. if (argp == NULL) {
  1235. MAGN_LOG("invalid argument.");
  1236. return -EINVAL;
  1237. }
  1238. if (copy_from_user(&mode, argp, sizeof(mode))) {
  1239. MAGN_LOG("copy_from_user failed.");
  1240. return -EFAULT;
  1241. }
  1242. ret = AKECS_SetMode(mode);
  1243. if (ret < 0)
  1244. return ret;
  1245. break;
  1246. case ECS_IOCTL_GETDATA:
  1247. ret = AKECS_GetData(sData, SENSOR_DATA_SIZE);
  1248. if (ret < 0)
  1249. return ret;
  1250. if (copy_to_user(argp, sData, sizeof(sData))) {
  1251. MAGN_LOG("copy_to_user failed.");
  1252. return -EFAULT;
  1253. }
  1254. break;
  1255. case ECS_IOCTL_SET_YPR_09911:
  1256. if (argp == NULL) {
  1257. MAGN_LOG("invalid argument.");
  1258. return -EINVAL;
  1259. }
  1260. if (copy_from_user(value, argp, sizeof(value))) {
  1261. MAGN_LOG("copy_from_user failed.");
  1262. return -EFAULT;
  1263. }
  1264. AKECS_SaveData(value);
  1265. break;
  1266. case ECS_IOCTL_GET_OPEN_STATUS:
  1267. status = AKECS_GetOpenStatus();
  1268. if (copy_to_user(argp, &status, sizeof(status))) {
  1269. MAGN_LOG("copy_to_user failed.");
  1270. return -EFAULT;
  1271. }
  1272. break;
  1273. case ECS_IOCTL_GET_CLOSE_STATUS:
  1274. status = AKECS_GetCloseStatus();
  1275. if (copy_to_user(argp, &status, sizeof(status))) {
  1276. MAGN_LOG("copy_to_user failed.");
  1277. return -EFAULT;
  1278. }
  1279. break;
  1280. case ECS_IOCTL_GET_OSENSOR_STATUS:
  1281. status = atomic_read(&o_flag);
  1282. if (copy_to_user(argp, &status, sizeof(status))) {
  1283. MAGN_LOG("copy_to_user failed.");
  1284. return -EFAULT;
  1285. }
  1286. break;
  1287. case ECS_IOCTL_GET_DELAY_09911:
  1288. delay[0] = (int)akmd_delay * 1000000;
  1289. delay[1] = (int)akmd_delay * 1000000;
  1290. delay[2] = (int)akmd_delay * 1000000;
  1291. if (copy_to_user(argp, delay, sizeof(delay))) {
  1292. MAGN_LOG("copy_to_user failed.");
  1293. return -EFAULT;
  1294. }
  1295. break;
  1296. case ECS_IOCTL_GET_LAYOUT_09911:
  1297. layout = atomic_read(&data->layout);
  1298. MAG_ERR("layout=%d\r\n", layout);
  1299. if (copy_to_user(argp, &layout, sizeof(char))) {
  1300. MAGN_LOG("copy_to_user failed.");
  1301. return -EFAULT;
  1302. }
  1303. break;
  1304. case MSENSOR_IOCTL_READ_CHIPINFO:
  1305. if (argp == NULL) {
  1306. MAG_ERR("IO parameter pointer is NULL!\r\n");
  1307. break;
  1308. }
  1309. akm09912_ReadChipInfo(buff, AKM09912_BUFSIZE);
  1310. if (copy_to_user(argp, buff, strlen(buff) + 1))
  1311. return -EFAULT;
  1312. break;
  1313. case MSENSOR_IOCTL_READ_SENSORDATA:
  1314. if (argp == NULL) {
  1315. MAG_ERR("IO parameter pointer is NULL!\r\n");
  1316. break;
  1317. }
  1318. AKECS_GetRawData(buff, AKM09912_BUFSIZE);
  1319. if (copy_to_user(argp, buff, strlen(buff) + 1))
  1320. return -EFAULT;
  1321. break;
  1322. case MSENSOR_IOCTL_SENSOR_ENABLE:
  1323. if (argp == NULL) {
  1324. MAG_ERR("IO parameter pointer is NULL!\r\n");
  1325. break;
  1326. }
  1327. if (copy_from_user(&enable, argp, sizeof(enable))) {
  1328. MAGN_LOG("copy_from_user failed.");
  1329. return -EFAULT;
  1330. }
  1331. MAGN_LOG("MSENSOR_IOCTL_SENSOR_ENABLE enable=%d!\r\n", enable);
  1332. factory_mode = 1;
  1333. if (1 == enable) {
  1334. atomic_set(&o_flag, 1);
  1335. atomic_set(&open_flag, 1);
  1336. } else {
  1337. atomic_set(&o_flag, 0);
  1338. if (atomic_read(&m_flag) == 0)
  1339. atomic_set(&open_flag, 0);
  1340. }
  1341. wake_up(&open_wq);
  1342. break;
  1343. case MSENSOR_IOCTL_READ_FACTORY_SENSORDATA:
  1344. if (argp == NULL) {
  1345. MAG_ERR("IO parameter pointer is NULL!\r\n");
  1346. break;
  1347. }
  1348. osensor_data = (struct hwm_sensor_data *)buff;
  1349. mutex_lock(&sensor_data_mutex);
  1350. osensor_data->values[0] = sensor_data[13] * CONVERT_O;
  1351. osensor_data->values[1] = sensor_data[14] * CONVERT_O;
  1352. osensor_data->values[2] = sensor_data[15] * CONVERT_O;
  1353. osensor_data->status = sensor_data[8];
  1354. osensor_data->value_divide = CONVERT_O_DIV;
  1355. mutex_unlock(&sensor_data_mutex);
  1356. sprintf(buff, "%x %x %x %x %x", osensor_data->values[0], osensor_data->values[1],
  1357. osensor_data->values[2], osensor_data->status, osensor_data->value_divide);
  1358. if (copy_to_user(argp, buff, strlen(buff) + 1))
  1359. return -EFAULT;
  1360. break;
  1361. default:
  1362. MAG_ERR("%s not supported = 0x%04x", __func__, cmd);
  1363. ret = -ENOIOCTLCMD;
  1364. break;
  1365. }
  1366. ret = 0;
  1367. return ret;
  1368. }
  1369. #ifdef CONFIG_COMPAT
  1370. static long akm09912_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  1371. {
  1372. long ret = 0;
  1373. void __user *arg32 = compat_ptr(arg);
  1374. if (!file->f_op || !file->f_op->unlocked_ioctl)
  1375. return -ENOTTY;
  1376. switch (cmd) {
  1377. case COMPAT_ECS_IOCTL_WRITE:
  1378. if (arg32 == NULL) {
  1379. MAGN_LOG("invalid argument.");
  1380. return -EINVAL;
  1381. }
  1382. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_WRITE, (unsigned long)arg32);
  1383. if (ret) {
  1384. MAGN_LOG("ECS_IOCTL_WRITE unlocked_ioctl failed.");
  1385. return ret;
  1386. }
  1387. break;
  1388. case COMPAT_ECS_IOCTL_RESET:
  1389. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_RESET, (unsigned long)arg32);
  1390. if (ret) {
  1391. MAGN_LOG("ECS_IOCTL_RESET unlocked_ioctl failed.");
  1392. return ret;
  1393. }
  1394. break;
  1395. case COMPAT_ECS_IOCTL_READ:
  1396. if (arg32 == NULL) {
  1397. MAGN_LOG("invalid argument.");
  1398. return -EINVAL;
  1399. }
  1400. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_READ, (unsigned long)arg32);
  1401. if (ret) {
  1402. MAGN_LOG("ECS_IOCTL_WRITE unlocked_ioctl failed.");
  1403. return ret;
  1404. }
  1405. break;
  1406. case COMPAT_ECS_IOCTL_GET_INFO:
  1407. if (arg32 == NULL) {
  1408. MAGN_LOG("invalid argument.");
  1409. return -EINVAL;
  1410. }
  1411. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_INFO, (unsigned long)(arg32));
  1412. if (ret) {
  1413. MAGN_LOG("ECS_IOCTL_GET_INFO unlocked_ioctl failed.");
  1414. return ret;
  1415. }
  1416. break;
  1417. case COMPAT_ECS_IOCTL_GET_CONF:
  1418. if (arg32 == NULL) {
  1419. MAGN_LOG("invalid argument.");
  1420. return -EINVAL;
  1421. }
  1422. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_CONF, (unsigned long)(arg32));
  1423. if (ret) {
  1424. MAGN_LOG("ECS_IOCTL_GET_CONF unlocked_ioctl failed.");
  1425. return ret;
  1426. }
  1427. break;
  1428. case COMPAT_ECS_IOCTL_SET_MODE:
  1429. if (arg32 == NULL) {
  1430. MAGN_LOG("invalid argument.");
  1431. return -EINVAL;
  1432. }
  1433. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_SET_MODE, (unsigned long)(arg32));
  1434. if (ret) {
  1435. MAGN_LOG("ECS_IOCTL_SET_MODE unlocked_ioctl failed.");
  1436. return ret;
  1437. }
  1438. break;
  1439. case COMPAT_ECS_IOCTL_GETDATA:
  1440. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GETDATA, (unsigned long)(arg32));
  1441. if (ret) {
  1442. MAGN_LOG("ECS_IOCTL_GETDATA unlocked_ioctl failed.");
  1443. return ret;
  1444. }
  1445. break;
  1446. case COMPAT_ECS_IOCTL_SET_YPR_09911:
  1447. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_SET_YPR_09911, (unsigned long)(arg32));
  1448. if (ret) {
  1449. MAGN_LOG("ECS_IOCTL_SET_YPR_09911 unlocked_ioctl failed.");
  1450. return ret;
  1451. }
  1452. break;
  1453. case COMPAT_ECS_IOCTL_GET_OPEN_STATUS:
  1454. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_OPEN_STATUS, (unsigned long)(arg32));
  1455. if (ret) {
  1456. MAGN_LOG("ECS_IOCTL_GET_OPEN_STATUS unlocked_ioctl failed.");
  1457. return ret;
  1458. }
  1459. break;
  1460. case COMPAT_ECS_IOCTL_GET_CLOSE_STATUS:
  1461. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_CLOSE_STATUS, (unsigned long)(arg32));
  1462. if (ret) {
  1463. MAGN_LOG("ECS_IOCTL_GET_CLOSE_STATUS unlocked_ioctl failed.");
  1464. return ret;
  1465. }
  1466. break;
  1467. case COMPAT_ECS_IOCTL_GET_OSENSOR_STATUS:
  1468. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_OSENSOR_STATUS, (unsigned long)(arg32));
  1469. if (ret) {
  1470. MAGN_LOG("ECS_IOCTL_GET_OSENSOR_STATUS unlocked_ioctl failed.");
  1471. return ret;
  1472. }
  1473. break;
  1474. case COMPAT_ECS_IOCTL_GET_DELAY_09911:
  1475. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_DELAY_09911, (unsigned long)(arg32));
  1476. if (ret) {
  1477. MAGN_LOG("ECS_IOCTL_GET_DELAY_09911 unlocked_ioctl failed.");
  1478. return ret;
  1479. }
  1480. break;
  1481. case COMPAT_ECS_IOCTL_GET_LAYOUT_09911:
  1482. ret = file->f_op->unlocked_ioctl(file, ECS_IOCTL_GET_LAYOUT_09911, (unsigned long)arg32);
  1483. if (ret) {
  1484. MAGN_LOG("ECS_IOCTL_GET_LAYOUT_09911 unlocked_ioctl failed.");
  1485. return ret;
  1486. }
  1487. break;
  1488. case COMPAT_MSENSOR_IOCTL_READ_CHIPINFO:
  1489. ret = file->f_op->unlocked_ioctl(file, MSENSOR_IOCTL_READ_CHIPINFO, (unsigned long)arg32);
  1490. if (ret) {
  1491. MAGN_LOG("MSENSOR_IOCTL_READ_CHIPINFO unlocked_ioctl failed.");
  1492. return ret;
  1493. }
  1494. break;
  1495. case COMPAT_MSENSOR_IOCTL_READ_SENSORDATA:
  1496. ret = file->f_op->unlocked_ioctl(file, MSENSOR_IOCTL_READ_SENSORDATA, (unsigned long)arg32);
  1497. if (ret) {
  1498. MAGN_LOG("MSENSOR_IOCTL_READ_SENSORDATA unlocked_ioctl failed.");
  1499. return ret;
  1500. }
  1501. break;
  1502. case COMPAT_MSENSOR_IOCTL_SENSOR_ENABLE:
  1503. if (arg32 == NULL) {
  1504. MAGN_LOG("invalid argument.");
  1505. return -EINVAL;
  1506. }
  1507. ret = file->f_op->unlocked_ioctl(file, MSENSOR_IOCTL_SENSOR_ENABLE, (unsigned long)(arg32));
  1508. if (ret) {
  1509. MAGN_LOG("MSENSOR_IOCTL_SENSOR_ENABLE unlocked_ioctl failed.");
  1510. return ret;
  1511. }
  1512. break;
  1513. case COMPAT_MSENSOR_IOCTL_READ_FACTORY_SENSORDATA:
  1514. if (arg32 == NULL) {
  1515. MAGN_LOG("invalid argument.");
  1516. return -EINVAL;
  1517. }
  1518. ret = file->f_op->unlocked_ioctl(file, MSENSOR_IOCTL_READ_FACTORY_SENSORDATA, (unsigned long)(arg32));
  1519. if (ret) {
  1520. MAGN_LOG("MSENSOR_IOCTL_READ_FACTORY_SENSORDATA unlocked_ioctl failed.");
  1521. return ret;
  1522. }
  1523. break;
  1524. default:
  1525. MAGN_LOG("%s not supported = 0x%04x", __func__, cmd);
  1526. ret = -ENOIOCTLCMD;
  1527. break;
  1528. }
  1529. return ret;
  1530. }
  1531. #endif
  1532. /*----------------------------------------------------------------------------*/
  1533. static const struct file_operations akm09912_fops = {
  1534. .owner = THIS_MODULE,
  1535. .open = akm09912_open,
  1536. .release = akm09912_release,
  1537. .unlocked_ioctl = akm09912_unlocked_ioctl,
  1538. #ifdef CONFIG_COMPAT
  1539. .compat_ioctl = akm09912_compat_ioctl,
  1540. #endif
  1541. };
  1542. /*----------------------------------------------------------------------------*/
  1543. static struct miscdevice akm09912_device = {
  1544. .minor = MISC_DYNAMIC_MINOR,
  1545. .name = "msensor",
  1546. .fops = &akm09912_fops,
  1547. };
  1548. #ifndef CONFIG_HAS_EARLYSUSPEND
  1549. /*----------------------------------------------------------------------------*/
  1550. static int akm09912_suspend(struct i2c_client *client, pm_message_t msg)
  1551. {
  1552. struct akm09912_i2c_data *obj = i2c_get_clientdata(client);
  1553. if (msg.event == PM_EVENT_SUSPEND)
  1554. akm09912_power(obj->hw, 0);
  1555. return 0;
  1556. }
  1557. /*----------------------------------------------------------------------------*/
  1558. static int akm09912_resume(struct i2c_client *client)
  1559. {
  1560. struct akm09912_i2c_data *obj = i2c_get_clientdata(client);
  1561. akm09912_power(obj->hw, 1);
  1562. return 0;
  1563. }
  1564. /*----------------------------------------------------------------------------*/
  1565. #else /*CONFIG_HAS_EARLY_SUSPEND is defined */
  1566. /*----------------------------------------------------------------------------*/
  1567. static void akm09912_early_suspend(struct early_suspend *h)
  1568. {
  1569. struct akm09912_i2c_data *obj = container_of(h, struct akm09912_i2c_data, early_drv);
  1570. int err = 0;
  1571. if (NULL == obj) {
  1572. MAG_ERR("null pointer!!\n");
  1573. return;
  1574. }
  1575. err = AKECS_SetMode(AK09912_MODE_POWERDOWN);
  1576. if (err < 0) {
  1577. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  1578. return;
  1579. }
  1580. akm09912_power(obj->hw, 0);
  1581. }
  1582. /*----------------------------------------------------------------------------*/
  1583. static void akm09912_late_resume(struct early_suspend *h)
  1584. {
  1585. struct akm09912_i2c_data *obj = container_of(h, struct akm09912_i2c_data, early_drv);
  1586. int err = 0;
  1587. if (NULL == obj) {
  1588. MAG_ERR("null pointer!!\n");
  1589. return;
  1590. }
  1591. akm09912_power(obj->hw, 1);
  1592. err = AKECS_SetMode(AK09912_MODE_SNG_MEASURE);
  1593. if (err < 0) {
  1594. MAGN_LOG("%s:%d Error.\n", __func__, __LINE__);
  1595. return;
  1596. }
  1597. }
  1598. /*----------------------------------------------------------------------------*/
  1599. #endif /*CONFIG_HAS_EARLYSUSPEND */
  1600. /*----------------------------------------------------------------------------*/
  1601. static int akm09912_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
  1602. {
  1603. strcpy(info->type, AKM09912_DEV_NAME);
  1604. return 0;
  1605. }
  1606. static int akm09912_m_enable(int en)
  1607. {
  1608. int value = 0;
  1609. int err = 0;
  1610. value = en;
  1611. factory_mode = 1;
  1612. if (value == 1) {
  1613. atomic_set(&m_flag, 1);
  1614. atomic_set(&open_flag, 1);
  1615. err = AKECS_SetMode(AK09912_MODE_SNG_MEASURE);
  1616. if (err < 0) {
  1617. MAG_ERR("%s:AKECS_SetMode Error.\n", __func__);
  1618. return err;
  1619. }
  1620. } else {
  1621. atomic_set(&m_flag, 0);
  1622. if (atomic_read(&o_flag) == 0) {
  1623. atomic_set(&open_flag, 0);
  1624. err = AKECS_SetMode(AK09912_MODE_POWERDOWN);
  1625. if (err < 0) {
  1626. MAG_ERR("%s:AKECS_SetMode Error.\n", __func__);
  1627. return err;
  1628. }
  1629. }
  1630. }
  1631. wake_up(&open_wq);
  1632. return err;
  1633. }
  1634. static int akm09912_m_set_delay(u64 ns)
  1635. {
  1636. int value = 0;
  1637. value = (int)ns / 1000 / 1000;
  1638. if (value <= 10)
  1639. akmd_delay = 10;
  1640. else
  1641. akmd_delay = value;
  1642. return 0;
  1643. }
  1644. static int akm09912_m_open_report_data(int open)
  1645. {
  1646. return 0;
  1647. }
  1648. static int akm09912_m_get_data(int *x, int *y, int *z, int *status)
  1649. {
  1650. mutex_lock(&sensor_data_mutex);
  1651. *x = sensor_data[5] * CONVERT_M;
  1652. *y = sensor_data[6] * CONVERT_M;
  1653. *z = sensor_data[7] * CONVERT_M;
  1654. *status = sensor_data[8];
  1655. mutex_unlock(&sensor_data_mutex);
  1656. return 0;
  1657. }
  1658. static int akm09912_o_enable(int en)
  1659. {
  1660. int value = 0;
  1661. int err = 0;
  1662. value = en;
  1663. if (value == 1) {
  1664. atomic_set(&o_flag, 1);
  1665. atomic_set(&open_flag, 1);
  1666. err = AKECS_SetMode(AK09912_MODE_SNG_MEASURE);
  1667. if (err < 0) {
  1668. MAG_ERR("%s:AKECS_SetMode Error.\n", __func__);
  1669. return err;
  1670. }
  1671. } else {
  1672. atomic_set(&o_flag, 0);
  1673. if (atomic_read(&m_flag) == 0) {
  1674. atomic_set(&open_flag, 0);
  1675. err = AKECS_SetMode(AK09912_MODE_POWERDOWN);
  1676. if (err < 0) {
  1677. MAG_ERR("%s:AKECS_SetMode Error.\n", __func__);
  1678. return err;
  1679. }
  1680. }
  1681. }
  1682. wake_up(&open_wq);
  1683. return err;
  1684. }
  1685. static int akm09912_o_set_delay(u64 ns)
  1686. {
  1687. int value = 0;
  1688. value = (int)ns / 1000 / 1000;
  1689. if (value <= 10)
  1690. akmd_delay = 10;
  1691. else
  1692. akmd_delay = value;
  1693. return 0;
  1694. }
  1695. static int akm09912_o_open_report_data(int open)
  1696. {
  1697. return 0;
  1698. }
  1699. static int akm09912_o_get_data(int *x, int *y, int *z, int *status)
  1700. {
  1701. mutex_lock(&sensor_data_mutex);
  1702. *x = sensor_data[13] * CONVERT_M;
  1703. *y = sensor_data[14] * CONVERT_M;
  1704. *z = sensor_data[15] * CONVERT_M;
  1705. *status = sensor_data[8];
  1706. mutex_unlock(&sensor_data_mutex);
  1707. return 0;
  1708. }
  1709. /*----------------------------------------------------------------------------*/
  1710. static int akm09912_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  1711. {
  1712. int err = 0;
  1713. struct i2c_client *new_client;
  1714. struct akm09912_i2c_data *data;
  1715. struct mag_control_path ctl = { 0 };
  1716. struct mag_data_path mag_data = { 0 };
  1717. MAGN_FUN();
  1718. data = kzalloc(sizeof(struct akm09912_i2c_data), GFP_KERNEL);
  1719. if (!data) {
  1720. err = -ENOMEM;
  1721. goto exit;
  1722. }
  1723. data->hw = hw;
  1724. atomic_set(&data->layout, data->hw->direction);
  1725. atomic_set(&data->trace, 0);
  1726. mutex_init(&sense_data_mutex);
  1727. mutex_init(&sensor_data_mutex);
  1728. init_waitqueue_head(&open_wq);
  1729. data->client = client;
  1730. new_client = data->client;
  1731. i2c_set_clientdata(new_client, data);
  1732. this_client = new_client;
  1733. /* Check connection */
  1734. err = AKECS_CheckDevice();
  1735. if (err < 0) {
  1736. MAG_ERR("AKM09912 akm09912_probe: check device connect error\n");
  1737. goto exit_init_failed;
  1738. }
  1739. /* Register sysfs attribute */
  1740. err = akm09912_create_attr(&(akm09912_init_info.platform_diver_addr->driver));
  1741. if (err) {
  1742. MAG_ERR("create attribute err = %d\n", err);
  1743. goto exit_sysfs_create_group_failed;
  1744. }
  1745. err = misc_register(&akm09912_device);
  1746. if (err) {
  1747. MAG_ERR("akm09912_device register failed\n");
  1748. goto exit_misc_device_register_failed;
  1749. }
  1750. ctl.is_use_common_factory = false;
  1751. ctl.m_enable = akm09912_m_enable;
  1752. ctl.m_set_delay = akm09912_m_set_delay;
  1753. ctl.m_open_report_data = akm09912_m_open_report_data;
  1754. ctl.o_enable = akm09912_o_enable;
  1755. ctl.o_set_delay = akm09912_o_set_delay;
  1756. ctl.o_open_report_data = akm09912_o_open_report_data;
  1757. ctl.is_report_input_direct = false;
  1758. ctl.is_support_batch = data->hw->is_batch_supported;
  1759. err = mag_register_control_path(&ctl);
  1760. if (err) {
  1761. MAG_ERR("register mag control path err\n");
  1762. goto exit_kfree;
  1763. }
  1764. mag_data.div_m = CONVERT_M_DIV;
  1765. mag_data.div_o = CONVERT_O_DIV;
  1766. mag_data.get_data_o = akm09912_o_get_data;
  1767. mag_data.get_data_m = akm09912_m_get_data;
  1768. err = mag_register_data_path(&mag_data);
  1769. if (err) {
  1770. MAG_ERR("register data control path err\n");
  1771. goto exit_kfree;
  1772. }
  1773. MAG_ERR("%s: OK\n", __func__);
  1774. akm09912_init_flag = 1;
  1775. return 0;
  1776. exit_sysfs_create_group_failed:
  1777. exit_init_failed:
  1778. exit_misc_device_register_failed:
  1779. exit_kfree:
  1780. kfree(data);
  1781. exit:
  1782. MAG_ERR("%s: err = %d\n", __func__, err);
  1783. akm09912_init_flag = -1;
  1784. return err;
  1785. }
  1786. /*----------------------------------------------------------------------------*/
  1787. static int akm09912_i2c_remove(struct i2c_client *client)
  1788. {
  1789. int err = 0;
  1790. err = akm09912_delete_attr(&(akm09912_init_info.platform_diver_addr->driver));
  1791. if (err)
  1792. MAG_ERR("akm09912_delete_attr fail: %d\n", err);
  1793. this_client = NULL;
  1794. i2c_unregister_device(client);
  1795. kfree(i2c_get_clientdata(client));
  1796. misc_deregister(&akm09912_device);
  1797. return 0;
  1798. }
  1799. /*----------------------------------------------------------------------------*/
  1800. static int akm09912_remove(void)
  1801. {
  1802. akm09912_power(hw, 0);
  1803. atomic_set(&dev_open_count, 0);
  1804. i2c_del_driver(&akm09912_i2c_driver);
  1805. return 0;
  1806. }
  1807. static int akm09912_local_init(void)
  1808. {
  1809. akm09912_power(hw, 1);
  1810. if (i2c_add_driver(&akm09912_i2c_driver)) {
  1811. MAG_ERR("i2c_add_driver error\n");
  1812. return -1;
  1813. }
  1814. if (-1 == akm09912_init_flag)
  1815. return -1;
  1816. return 0;
  1817. }
  1818. /*----------------------------------------------------------------------------*/
  1819. static int __init akm09912_init(void)
  1820. {
  1821. const char *name = "mediatek,akm09912";
  1822. hw = get_mag_dts_func(name, hw);
  1823. if (!hw)
  1824. MAGN_ERR("get dts info fail\n");
  1825. mag_driver_add(&akm09912_init_info);
  1826. return 0;
  1827. }
  1828. /*----------------------------------------------------------------------------*/
  1829. static void __exit akm09912_exit(void)
  1830. {
  1831. MAGN_FUN();
  1832. }
  1833. /*----------------------------------------------------------------------------*/
  1834. module_init(akm09912_init);
  1835. module_exit(akm09912_exit);
  1836. MODULE_AUTHOR("viral wang <viral_wang@htc.com>");
  1837. MODULE_DESCRIPTION("AKM09912 compass driver");
  1838. MODULE_LICENSE("GPL");
  1839. MODULE_VERSION(DRIVER_VERSION);