PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/misc/bma150_spi.c

http://github.com/toastcfh/CdMa-HeRoC-2.6.29
C | 510 lines | 363 code | 79 blank | 68 comment | 51 complexity | 1ea273fa6268f298467f981c50154ae7 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.0
  1. /* drivers/misc/bma150_spi.c - bma150 G-sensor driver
  2. *
  3. * Copyright (C) 2009 HTC Corporation.
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/i2c.h>
  16. #include <linux/slab.h>
  17. #include <linux/miscdevice.h>
  18. #include <asm/uaccess.h>
  19. #include <linux/delay.h>
  20. #include <linux/input.h>
  21. #include <linux/bma150.h>
  22. #include <asm/gpio.h>
  23. #include <linux/earlysuspend.h>
  24. #include <linux/platform_device.h>
  25. #include <mach/atmega_microp.h>
  26. #define MAGIC_RETURN_NO 77
  27. static void spi_bma150_init_callback(void);
  28. struct early_suspend bma_early_suspend;
  29. static struct mutex set_normal_mode_mutex;
  30. static int set_normal_mode_cnt;
  31. static struct microp_gs_callback gs_callback = {
  32. .gs_init = spi_bma150_init_callback
  33. };
  34. static struct bma150_platform_data *this_pdata;
  35. static struct mutex gsensor_RW_mutex;
  36. static int spi_microp_enable(uint8_t on)
  37. {
  38. int ret;
  39. ret = microp_spi_vote_enable(SPI_GSENSOR, on);
  40. if (ret < 0) {
  41. printk(KERN_ERR "%s: i2c_write_block fail\n", __func__);
  42. return ret;
  43. }
  44. return ret;
  45. }
  46. static int spi_gsensor_read(uint8_t *data)
  47. {
  48. int ret;
  49. mutex_lock(&gsensor_RW_mutex);
  50. ret = microp_i2c_write(MICROP_I2C_WCMD_GSENSOR_REG_DATA_REQ, data, 1);
  51. if (ret < 0) {
  52. printk(KERN_ERR "%s: i2c_write_block fail\n", __func__);
  53. return ret;
  54. }
  55. ret = microp_i2c_read(MICROP_I2C_RCMD_GSENSOR_REG_DATA, data, 2);
  56. if (ret < 0) {
  57. printk(KERN_ERR "%s: i2c_read_block fail\n", __func__);
  58. return ret;
  59. }
  60. mutex_unlock(&gsensor_RW_mutex);
  61. return ret;
  62. }
  63. static int spi_gsensor_write(uint8_t *data)
  64. {
  65. int ret;
  66. mutex_lock(&gsensor_RW_mutex);
  67. ret = microp_i2c_write(MICROP_I2C_WCMD_GSENSOR_REG, data, 2);
  68. if (ret < 0) {
  69. printk(KERN_ERR "%s: i2c_write_block fail\n", __func__);
  70. return ret;
  71. }
  72. mutex_unlock(&gsensor_RW_mutex);
  73. return ret;
  74. }
  75. static int spi_gsensor_init_hw(void)
  76. {
  77. char buffer[2];
  78. memset(buffer, 0x0, sizeof(buffer));
  79. buffer[0] = RANGE_BWIDTH_REG;
  80. if (spi_gsensor_read(buffer) < 0)
  81. return -EIO;
  82. buffer[1] = (buffer[1]&0xe0);
  83. buffer[0] = RANGE_BWIDTH_REG;
  84. if (spi_gsensor_write(buffer) < 0)
  85. return -EIO;
  86. buffer[0] = SMB150_CONF2_REG;
  87. if (spi_gsensor_read(buffer) < 0)
  88. return -EIO;
  89. buffer[1] = buffer[1]|1<<3;
  90. buffer[0] = SMB150_CONF2_REG;
  91. if (spi_gsensor_write(buffer) < 0)
  92. return -EIO;
  93. return 0;
  94. }
  95. /*
  96. static int spi_gsensor_read_version(void)
  97. {
  98. uint8_t buffer[2];
  99. int ret = -EIO;
  100. buffer[0] = VERSION_REG;
  101. buffer[1] = 1;
  102. ret = spi_gsensor_read(buffer);
  103. if (ret < 0) {
  104. printk(KERN_ERR "%s: get al_version fail(%d)\n", __func__, ret);
  105. return ret;
  106. }
  107. printk(KERN_INFO "%s: al_version: 0x%2.2X\n", __func__, buffer[0]);
  108. buffer[0] = CHIP_ID_REG;
  109. buffer[1] = 1;
  110. ret = spi_gsensor_read(buffer);
  111. if (ret < 0) {
  112. printk(KERN_ERR "%s: get chip_id fail(%d)\n", __func__, ret);
  113. return ret;
  114. }
  115. printk(KERN_INFO "%s: chip_id: 0x%2.2X\n", __func__, buffer[0]);
  116. return 0;
  117. }
  118. */
  119. static int spi_bma150_TransRBuff(short *rbuf)
  120. {
  121. int ret;
  122. unsigned char buffer[6];
  123. memset(buffer, 0, 6);
  124. mutex_lock(&gsensor_RW_mutex);
  125. buffer[0] = 1;
  126. ret = microp_i2c_write(MICROP_I2C_WCMD_GSENSOR_DATA_REQ, buffer, 1);
  127. if (ret < 0) {
  128. printk(KERN_ERR "%s: i2c_write_block fail\n", __func__);
  129. return ret;
  130. }
  131. if (this_pdata && this_pdata->microp_new_cmd &&
  132. this_pdata->microp_new_cmd == 1) {
  133. /*printk(KERN_DEBUG "%s: New MicroP command\n", __func__);*/
  134. ret = microp_i2c_read(MICROP_I2C_RCMD_GSENSOR_DATA, buffer, 6);
  135. rbuf[0] = buffer[0]<<2|buffer[1]>>6;
  136. if (rbuf[0]&0x200)
  137. rbuf[0] -= 1<<10;
  138. rbuf[1] = buffer[2]<<2|buffer[3]>>6;
  139. if (rbuf[1]&0x200)
  140. rbuf[1] -= 1<<10;
  141. rbuf[2] = buffer[4]<<2|buffer[5]>>6;
  142. if (rbuf[2]&0x200)
  143. rbuf[2] -= 1<<10;
  144. } else {
  145. /* For Passion with V01 ~ V05 Microp */
  146. /*printk(KERN_DEBUG "%s: Old MicroP command\n", __func__);*/
  147. ret = microp_i2c_read(MICROP_I2C_RCMD_GSENSOR_X_DATA,
  148. buffer, 2);
  149. if (ret < 0) {
  150. printk(KERN_ERR "%s: i2c_read_block fail\n", __func__);
  151. return ret;
  152. }
  153. rbuf[0] = buffer[0]<<2|buffer[1]>>6;
  154. if (rbuf[0]&0x200)
  155. rbuf[0] -= 1<<10;
  156. ret = microp_i2c_read(MICROP_I2C_RCMD_GSENSOR_Y_DATA,
  157. buffer, 2);
  158. if (ret < 0) {
  159. printk(KERN_ERR "%s: i2c_read_block fail\n", __func__);
  160. return ret;
  161. }
  162. rbuf[1] = buffer[0]<<2|buffer[1]>>6;
  163. if (rbuf[1]&0x200)
  164. rbuf[1] -= 1<<10;
  165. ret = microp_i2c_read(MICROP_I2C_RCMD_GSENSOR_Z_DATA,
  166. buffer, 2);
  167. if (ret < 0) {
  168. printk(KERN_ERR "%s: i2c_read_block fail\n", __func__);
  169. return ret;
  170. }
  171. rbuf[2] = buffer[0]<<2|buffer[1]>>6;
  172. if (rbuf[2]&0x200)
  173. rbuf[2] -= 1<<10;
  174. }
  175. /* printk("X=%d, Y=%d, Z=%d\n",rbuf[0],rbuf[1],rbuf[2]);*/
  176. /* printk(KERN_DEBUG "%s: 0x%2.2X 0x%2.2X 0x%2.2X \
  177. 0x%2.2X 0x%2.2X 0x%2.2X\n",
  178. __func__, buffer[0], buffer[1], buffer[2], \
  179. buffer[3], buffer[4], buffer[5]);*/
  180. mutex_unlock(&gsensor_RW_mutex);
  181. return 1;
  182. }
  183. static int __spi_bma150_set_mode(char mode)
  184. {
  185. char buffer[2];
  186. int ret;
  187. if (mode == BMA_MODE_NORMAL) {
  188. spi_microp_enable(1);
  189. printk(KERN_INFO "%s: BMA get into NORMAL mode!\n",
  190. __func__);
  191. }
  192. buffer[0] = SMB150_CTRL_REG;
  193. ret = spi_gsensor_read(buffer);
  194. if (ret < 0)
  195. return -1;
  196. buffer[1] = (buffer[1]&0xfe)|mode;
  197. buffer[0] = SMB150_CTRL_REG;
  198. ret = spi_gsensor_write(buffer);
  199. if (mode == BMA_MODE_SLEEP) {
  200. spi_microp_enable(0);
  201. printk(KERN_INFO "%s: BMA get into SLEEP mode!\n",
  202. __func__);
  203. }
  204. return ret;
  205. }
  206. static int spi_bma150_set_mode(char mode)
  207. {
  208. int ret;
  209. printk(KERN_DEBUG "%s: set_normal_mode_cnt = %d, mode = %d\n",
  210. __func__, set_normal_mode_cnt, mode);
  211. if (mode == BMA_MODE_NORMAL) {
  212. if (!set_normal_mode_cnt++) /* 0 -> 1 */
  213. ret = __spi_bma150_set_mode(BMA_MODE_NORMAL);
  214. else
  215. return -MAGIC_RETURN_NO;
  216. } else {
  217. if (!--set_normal_mode_cnt) /* 1 -> 0 */
  218. ret = __spi_bma150_set_mode(BMA_MODE_SLEEP);
  219. else
  220. return -MAGIC_RETURN_NO;
  221. }
  222. return ret;
  223. }
  224. static int spi_bma150_open(struct inode *inode, struct file *file)
  225. {
  226. set_normal_mode_cnt = 0;
  227. return nonseekable_open(inode, file);
  228. }
  229. static int spi_bma150_release(struct inode *inode, struct file *file)
  230. {
  231. return 0;
  232. }
  233. static int spi_bma150_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  234. unsigned long arg)
  235. {
  236. void __user *argp = (void __user *)arg;
  237. char rwbuf[8];
  238. char *toRbuf;
  239. int ret = -1;
  240. short buf[8], temp;
  241. switch (cmd) {
  242. case BMA_IOCTL_READ:
  243. case BMA_IOCTL_WRITE:
  244. case BMA_IOCTL_SET_MODE:
  245. if (copy_from_user(&rwbuf, argp, sizeof(rwbuf)))
  246. return -EFAULT;
  247. break;
  248. case BMA_IOCTL_READ_ACCELERATION:
  249. if (copy_from_user(&buf, argp, sizeof(buf)))
  250. return -EFAULT;
  251. break;
  252. default:
  253. break;
  254. }
  255. switch (cmd) {
  256. case BMA_IOCTL_INIT:
  257. ret = spi_gsensor_init_hw();
  258. if (ret < 0)
  259. return ret;
  260. break;
  261. case BMA_IOCTL_READ:
  262. if (rwbuf[0] < 1)
  263. return -EINVAL;
  264. ret = spi_gsensor_read(&rwbuf[1]);
  265. if (ret < 0)
  266. return ret;
  267. break;
  268. case BMA_IOCTL_WRITE:
  269. if (rwbuf[0] < 2)
  270. return -EINVAL;
  271. ret = spi_gsensor_write(&rwbuf[1]);
  272. if (ret < 0)
  273. return ret;
  274. break;
  275. case BMA_IOCTL_READ_ACCELERATION:
  276. ret = spi_bma150_TransRBuff(&buf[0]);
  277. if (ret < 0)
  278. return ret;
  279. break;
  280. case BMA_IOCTL_SET_MODE:
  281. printk(KERN_INFO "%s: Set mode by ioctl!\n",
  282. __func__);
  283. mutex_lock(&set_normal_mode_mutex);
  284. spi_bma150_set_mode(rwbuf[0]);
  285. mutex_unlock(&set_normal_mode_mutex);
  286. break;
  287. case BMA_IOCTL_GET_INT:
  288. temp = 0;
  289. break;
  290. default:
  291. return -ENOTTY;
  292. }
  293. switch (cmd) {
  294. case BMA_IOCTL_READ:
  295. toRbuf = &rwbuf[1];
  296. if (copy_to_user(argp, toRbuf, sizeof(rwbuf)-1))
  297. return -EFAULT;
  298. break;
  299. case BMA_IOCTL_READ_ACCELERATION:
  300. if (copy_to_user(argp, &buf, sizeof(buf)))
  301. return -EFAULT;
  302. break;
  303. case BMA_IOCTL_GET_INT:
  304. if (copy_to_user(argp, &temp, sizeof(temp)))
  305. return -EFAULT;
  306. break;
  307. default:
  308. break;
  309. }
  310. return 0;
  311. }
  312. static struct file_operations spi_bma_fops = {
  313. .owner = THIS_MODULE,
  314. .open = spi_bma150_open,
  315. .release = spi_bma150_release,
  316. .ioctl = spi_bma150_ioctl,
  317. };
  318. static struct miscdevice spi_bma_device = {
  319. .minor = MISC_DYNAMIC_MINOR,
  320. .name = BMA150_G_SENSOR_NAME,
  321. .fops = &spi_bma_fops,
  322. };
  323. static void bma150_early_suspend(struct early_suspend *handler)
  324. {
  325. int ret;
  326. mutex_lock(&set_normal_mode_mutex);
  327. ret = spi_bma150_set_mode(BMA_MODE_SLEEP);
  328. mutex_unlock(&set_normal_mode_mutex);
  329. printk(KERN_DEBUG
  330. "%s: spi_bma150_set_mode returned = %d!\n",
  331. __func__, ret);
  332. }
  333. static void bma150_early_resume(struct early_suspend *handler)
  334. {
  335. int ret;
  336. mutex_lock(&set_normal_mode_mutex);
  337. ret = spi_bma150_set_mode(BMA_MODE_NORMAL);
  338. mutex_unlock(&set_normal_mode_mutex);
  339. printk(KERN_DEBUG
  340. "%s: spi_bma150_set_mode returned = %d!\n",
  341. __func__, ret);
  342. }
  343. static void spi_bma150_init_callback(void)
  344. {
  345. int ret;
  346. ret = spi_microp_enable(1);
  347. if (ret)
  348. printk(KERN_ERR "%s: spi_microp_enable(1) fail!\n",
  349. __func__);
  350. mutex_lock(&set_normal_mode_mutex);
  351. ret = __spi_bma150_set_mode(BMA_MODE_SLEEP);
  352. mutex_unlock(&set_normal_mode_mutex);
  353. if (ret)
  354. printk(KERN_DEBUG
  355. "%s: __spi_bma150_set_mode(BMA_MODE_SLEEP) fail!\n",
  356. __func__);
  357. }
  358. static int spi_gsensor_initial(void)
  359. {
  360. int ret;
  361. /* ret = spi_microp_enable(1);
  362. if (ret < 0) {
  363. printk(KERN_ERR "%s: spi_microp_enable fail\n", __func__);
  364. return ret;
  365. }*/
  366. /* ret = spi_gsensor_read_version();
  367. if (ret < 0) {
  368. printk(KERN_ERR "%s: get version fail\n", __func__);
  369. return ret;
  370. }*/
  371. /* ret = microp_gsensor_init_hw(client);
  372. if (ret < 0) {
  373. printk(KERN_ERR "%s: init g-sensor fail\n", __func__);
  374. return ret;
  375. }
  376. */
  377. ret = misc_register(&spi_bma_device);
  378. if (ret < 0) {
  379. printk(KERN_ERR "%s: init misc_register fail\n", __func__);
  380. return ret;
  381. }
  382. mutex_init(&set_normal_mode_mutex);
  383. mutex_init(&gsensor_RW_mutex);
  384. set_normal_mode_cnt = 0;
  385. ret = microp_register_gs_callback(&gs_callback);
  386. printk(KERN_DEBUG "%s: ret = %d\n", __func__, ret);
  387. if (ret == 0)
  388. spi_bma150_init_callback();
  389. bma_early_suspend.suspend = bma150_early_suspend;
  390. bma_early_suspend.resume = bma150_early_resume;
  391. register_early_suspend(&bma_early_suspend);
  392. return 0;
  393. }
  394. static int spi_bma150_probe(struct platform_device *pdev)
  395. {
  396. printk(KERN_INFO "%s: G-sensor connect with microP: "
  397. "start initial\n", __func__);
  398. this_pdata = pdev->dev.platform_data;
  399. /*
  400. printk(KERN_DEBUG "%s: this_pdata->microp_new_cmd = %d\n",
  401. __func__, this_pdata->microp_new_cmd);
  402. */
  403. spi_gsensor_initial();
  404. return 0;
  405. }
  406. static int spi_bma150_remove(struct platform_device *pdev)
  407. {
  408. return 0;
  409. }
  410. static struct platform_driver spi_bma150_driver = {
  411. .probe = spi_bma150_probe,
  412. .remove = spi_bma150_remove,
  413. .driver = {
  414. .name = BMA150_G_SENSOR_NAME,
  415. .owner = THIS_MODULE,
  416. },
  417. };
  418. static int __init spi_bma150_init(void)
  419. {
  420. return platform_driver_register(&spi_bma150_driver);
  421. }
  422. static void __exit spi_bma150_exit(void)
  423. {
  424. platform_driver_unregister(&spi_bma150_driver);
  425. }
  426. module_init(spi_bma150_init);
  427. module_exit(spi_bma150_exit);
  428. MODULE_DESCRIPTION("BMA150 G-sensor driver");
  429. MODULE_LICENSE("GPL");