Advertisement
motafoca

mmc31xx.c

May 5th, 2011
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.44 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2010 MEMSIC, Inc.
  3. *
  4. * Initial Code:
  5. * Robbie Cao
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. */
  22.  
  23. #include <linux/kernel.h>
  24. #include <linux/init.h>
  25. #include <linux/module.h>
  26. #include <linux/slab.h>
  27. #include <linux/jiffies.h>
  28. #include <linux/i2c.h>
  29. #include <linux/i2c-dev.h>
  30. #include <linux/miscdevice.h>
  31. #include <linux/mutex.h>
  32. #include <linux/mm.h>
  33. #include <linux/device.h>
  34. #include <linux/fs.h>
  35. #include <linux/delay.h>
  36. #include <linux/sysctl.h>
  37. #include <asm/uaccess.h>
  38. #include <mach/vreg.h>
  39.  
  40. #include <linux/i2c/mmc31xx.h>
  41.  
  42. #define DEBUG 0
  43. #define MAX_FAILURE_COUNT 3
  44.  
  45. #define MMC31XX_DELAY_TM 10 /* ms */
  46. #define MMC31XX_DELAY_SET 10 /* ms */
  47. #define MMC31XX_DELAY_RST 10 /* ms */
  48. #define MMC31XX_DELAY_STDN 1 /* ms */
  49.  
  50. #define MMC31XX_RETRY_COUNT 3
  51. #define MMC31XX_RESET_INTV 10
  52.  
  53. #define MMC31XX_DEV_NAME "mmc31xx"
  54. #define LDO_LCD "ldo3"
  55.  
  56. static u32 read_idx = 0;
  57. struct class *mag_class;
  58.  
  59. static struct i2c_client *this_client;
  60.  
  61. static int mmc31xx_i2c_rx_data(char *buf, int len)
  62. {
  63. uint8_t i;
  64. struct i2c_msg msgs[] = {
  65. {
  66. .addr = this_client->addr,
  67. .flags = 0,
  68. .len = 1,
  69. .buf = buf,
  70. },
  71. {
  72. .addr = this_client->addr,
  73. .flags = I2C_M_RD,
  74. .len = len,
  75. .buf = buf,
  76. }
  77. };
  78.  
  79. for (i = 0; i < MMC31XX_RETRY_COUNT; i++) {
  80. if (i2c_transfer(this_client->adapter, msgs, 2) >= 0) {
  81. break;
  82. }
  83. mdelay(10);
  84. }
  85.  
  86. if (i >= MMC31XX_RETRY_COUNT) {
  87. pr_err("%s: retry over %d\n", __FUNCTION__, MMC31XX_RETRY_COUNT);
  88. return -EIO;
  89. }
  90.  
  91. return 0;
  92. }
  93.  
  94. static int mmc31xx_i2c_tx_data(char *buf, int len)
  95. {
  96. uint8_t i;
  97. struct i2c_msg msg[] = {
  98. {
  99. .addr = this_client->addr,
  100. .flags = 0,
  101. .len = len,
  102. .buf = buf,
  103. }
  104. };
  105.  
  106. for (i = 0; i < MMC31XX_RETRY_COUNT; i++) {
  107. if (i2c_transfer(this_client->adapter, msg, 1) >= 0) {
  108. break;
  109. }
  110. mdelay(10);
  111. }
  112.  
  113. if (i >= MMC31XX_RETRY_COUNT) {
  114. pr_err("%s: retry over %d\n", __FUNCTION__, MMC31XX_RETRY_COUNT);
  115. return -EIO;
  116. }
  117.  
  118. return 0;
  119. }
  120.  
  121. /*************************************************************************/
  122. /* BMA023 Sysfs */
  123. /*************************************************************************/
  124. static ssize_t mmc31xx_fs_read(struct device *dev, struct device_attribute *attr, char *buf)
  125. {
  126. unsigned char data[16] = {0};
  127. int vec[3] = {0};
  128. int count;
  129. int res = 0;
  130.  
  131. // Write 0x00000010 to 0x00000000
  132. data[0] = MMC31XX_REG_CTRL;
  133. data[1] = MMC31XX_CTRL_SET;
  134. if (mmc31xx_i2c_tx_data(data, 2) < 0) {
  135. return 0;
  136. }
  137. /* wait external capacitor charging done for next SET/RESET */
  138. msleep(MMC31XX_DELAY_SET);
  139.  
  140. // Write 0x00000001 to 0x00000000
  141. data[0] = MMC31XX_REG_CTRL;
  142. data[1] = MMC31XX_CTRL_TM;
  143. res = mmc31xx_i2c_tx_data(data, 2);
  144.  
  145. /* wait TM done for coming data read */
  146. msleep(MMC31XX_DELAY_TM);
  147. data[0] = MMC31XX_REG_DATA;
  148. if (mmc31xx_i2c_rx_data(data, 6) < 0) {
  149. return 0;
  150. }
  151. vec[1] = data[0] << 8 | data[1];
  152. vec[0] = data[2] << 8 | data[3];
  153. vec[2] = 7414 - (data[4] << 8 | data[5]);
  154. #if DEBUG
  155. printk("[X - %04x] [Y - %04x] [Z - %04x]\n",
  156. vec[0], vec[1], vec[2]);
  157. #endif
  158.  
  159. printk("x: %d,y: %d,z: %d\n", vec[0], vec[1], vec[2]);
  160. count = sprintf(buf,"%d,%d,%d\n", vec[0], vec[1], vec[2]);
  161.  
  162. return count;
  163. }
  164.  
  165. static ssize_t mmc31xx_fs_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
  166. {
  167. //buf[size]=0;
  168. printk("input data --> %s\n", buf);
  169.  
  170. return size;
  171. }
  172.  
  173. static ssize_t mmc31xx_power_on(struct device *dev, struct device_attribute *attr, char *buf)
  174. {
  175. unsigned char data[16] = {0};
  176. int count;
  177. int res = 0;
  178.  
  179. data[0] = MMC31XX_REG_CTRL;
  180. data[1] = MMC31XX_CTRL_TM;
  181. res = mmc31xx_i2c_tx_data(data, 2);
  182.  
  183. /* wait TM done for coming data read */
  184. msleep(MMC31XX_DELAY_TM);
  185.  
  186. #if DEBUG
  187. printk("[%s] result of i2c writing: %d\n", __func__, !(res < 0));
  188. #endif
  189. count = sprintf(buf,"%d\n", !(res < 0));
  190.  
  191. return count;
  192. }
  193. static DEVICE_ATTR(read_mag, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, mmc31xx_fs_read, mmc31xx_fs_write);
  194. static DEVICE_ATTR(power_on, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, mmc31xx_power_on, NULL);
  195.  
  196. static int mmc31xx_open(struct inode *inode, struct file *file)
  197. {
  198. return nonseekable_open(inode, file);
  199. }
  200.  
  201. static int mmc31xx_release(struct inode *inode, struct file *file)
  202. {
  203. return 0;
  204. }
  205.  
  206. static int mmc31xx_ioctl(struct inode *inode, struct file *file,
  207. unsigned int cmd, unsigned long arg)
  208. {
  209. void __user *pa = (void __user *)arg;
  210. unsigned char data[16] = {0};
  211. int vec[3] = {0};
  212.  
  213. switch (cmd) {
  214. case MMC31XX_IOC_TM:
  215. data[0] = MMC31XX_REG_CTRL;
  216. data[1] = MMC31XX_CTRL_TM;
  217. if (mmc31xx_i2c_tx_data(data, 2) < 0) {
  218. return -EFAULT;
  219. }
  220. /* wait TM done for coming data read */
  221. msleep(MMC31XX_DELAY_TM);
  222. break;
  223. case MMC31XX_IOC_SET:
  224. data[0] = MMC31XX_REG_CTRL;
  225. data[1] = MMC31XX_CTRL_SET;
  226. if (mmc31xx_i2c_tx_data(data, 2) < 0) {
  227. return -EFAULT;
  228. }
  229. /* wait external capacitor charging done for next SET/RESET */
  230. msleep(MMC31XX_DELAY_SET);
  231. break;
  232. case MMC31XX_IOC_RESET:
  233. data[0] = MMC31XX_REG_CTRL;
  234. data[1] = MMC31XX_CTRL_RST;
  235. if (mmc31xx_i2c_tx_data(data, 2) < 0) {
  236. return -EFAULT;
  237. }
  238. /* wait external capacitor charging done for next SET/RESET */
  239. msleep(MMC31XX_DELAY_RST);
  240. break;
  241. case MMC31XX_IOC_READ:
  242. data[0] = MMC31XX_REG_DATA;
  243. if (mmc31xx_i2c_rx_data(data, 6) < 0) {
  244. return -EFAULT;
  245. }
  246. vec[1] = data[0] << 8 | data[1];
  247. vec[0] = data[2] << 8 | data[3];
  248. vec[2] = 7414 - (data[4] << 8 | data[5]);
  249. #if DEBUG
  250. printk("[X - %04x] [Y - %04x] [Z - %04x]\n",
  251. vec[0], vec[1], vec[2]);
  252. #endif
  253. if (copy_to_user(pa, vec, sizeof(vec))) {
  254. return -EFAULT;
  255. }
  256. break;
  257. case MMC31XX_IOC_READXYZ:
  258. /* do RESET/SET every MMC31XX_RESET_INTV times read */
  259. if ((read_idx >= MMC31XX_RESET_INTV)) {
  260. /* RESET */
  261. data[0] = MMC31XX_REG_CTRL;
  262. data[1] = MMC31XX_CTRL_RST;
  263. /* not check return value here, assume it always OK */
  264. mmc31xx_i2c_tx_data(data, 2);
  265. #if DEBUG
  266. printk(KERN_ERR "RESET\n");
  267. #endif
  268. /* wait external capacitor charging done for next SET/RESET */
  269. msleep(MMC31XX_DELAY_SET);
  270. /* SET */
  271. data[0] = MMC31XX_REG_CTRL;
  272. data[1] = MMC31XX_CTRL_SET;
  273. /* not check return value here, assume it always OK */
  274. mmc31xx_i2c_tx_data(data, 2);
  275. #if DEBUG
  276. printk(KERN_ERR "SET\n");
  277. #endif
  278. msleep(MMC31XX_DELAY_STDN);
  279. read_idx = 0;
  280. }
  281.  
  282. /* send TM cmd before read */
  283. data[0] = MMC31XX_REG_CTRL;
  284. data[1] = MMC31XX_CTRL_TM;
  285. /* not check return value here, assume it always OK */
  286. if(mmc31xx_i2c_tx_data(data, 2) < 0){
  287. printk(KERN_ERR "[mmc31xx] i2c write is failed\n");
  288. return -EFAULT;
  289. }
  290. #if 0
  291. printk(KERN_ERR "[mmc31xx] i2c read ctl reg before delay\n");
  292. data[0] = MMC31XX_REG_CTRL;
  293. if (mmc31xx_i2c_rx_data(data, 2) < 0) {
  294. printk(KERN_ERR "[mmc31xx] i2c read is failed\n");
  295. return -EFAULT;
  296. }
  297. printk("[mmc31xx] before data[0] = %x\n", data[0]);
  298. /* wait TM done for coming data read */
  299. #endif
  300. msleep(MMC31XX_DELAY_TM);
  301. #if 0
  302. printk(KERN_ERR "[mmc31xx] i2c read ctl reg after delay\n");
  303. data[0] = MMC31XX_REG_CTRL;
  304. if (mmc31xx_i2c_rx_data(data, 2) < 0) {
  305. printk(KERN_ERR "[mmc31xx] i2c read is failed\n");
  306. return -EFAULT;
  307. }
  308. printk("[mmc31xx] after data[0] = %x\n", data[0]);
  309. #endif
  310. /* read xyz raw data */
  311. read_idx++;
  312. data[0] = MMC31XX_REG_DATA;
  313. if (mmc31xx_i2c_rx_data(data, 6) < 0) {
  314. printk(KERN_ERR "[mmc31xx] i2c read is failed\n");
  315. return -EFAULT;
  316. }
  317. vec[1] = data[0] << 8 | data[1];
  318. vec[0] = data[2] << 8 | data[3];
  319. vec[2] = 7414 - (data[4] << 8 | data[5]);
  320. #if DEBUG
  321. printk("[X - %04x] [Y - %04x] [Z - %04x]\n",
  322. vec[0], vec[1], vec[2]);
  323. #endif
  324. if (copy_to_user(pa, vec, sizeof(vec))) {
  325. return -EFAULT;
  326. }
  327. break;
  328. default:
  329. break;
  330. }
  331.  
  332. return 0;
  333. }
  334.  
  335. static ssize_t mmc31xx_show(struct device *dev, struct device_attribute *attr, char *buf)
  336. {
  337. ssize_t ret = 0;
  338.  
  339. sprintf(buf, "MMC31XX");
  340. ret = strlen(buf) + 1;
  341.  
  342. return ret;
  343. }
  344.  
  345. static DEVICE_ATTR(mmc31xx, S_IRUGO, mmc31xx_show, NULL);
  346.  
  347. static struct file_operations mmc31xx_fops = {
  348. .owner = THIS_MODULE,
  349. .open = mmc31xx_open,
  350. .release = mmc31xx_release,
  351. .ioctl = mmc31xx_ioctl,
  352. };
  353.  
  354. static struct miscdevice mmc31xx_device = {
  355. .minor = MISC_DYNAMIC_MINOR,
  356. .name = MMC31XX_DEV_NAME,
  357. .fops = &mmc31xx_fops,
  358. };
  359.  
  360. int mmc31xx_probe(struct i2c_client *client, const struct i2c_device_id *id)
  361. {
  362. struct vreg *mmc31xx_vreg = vreg_get(0, LDO_LCD);
  363. unsigned char data[16] = {0};
  364. int res = 0;
  365.  
  366. printk(KERN_ERR "[mmc31xx_probe] +\n");
  367.  
  368. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  369. pr_err("%s: functionality check failed\n", __FUNCTION__);
  370. res = -ENODEV;
  371. goto out;
  372. }
  373. this_client = client;
  374.  
  375. res = misc_register(&mmc31xx_device);
  376. if (res) {
  377. pr_err("%s: mmc31xx_device register failed\n", __FUNCTION__);
  378. goto out;
  379. }
  380. res = device_create_file(&client->dev, &dev_attr_mmc31xx);
  381. if (res) {
  382. pr_err("%s: device_create_file failed\n", __FUNCTION__);
  383. goto out_deregister;
  384. }
  385. // Power On
  386. if(vreg_enable(mmc31xx_vreg))
  387. printk(KERN_ERR "vreg_enable: ldo15 vreg operation failed\n");
  388.  
  389. /* send ST cmd to mag sensor first of all */
  390. data[0] = MMC31XX_REG_CTRL;
  391. data[1] = MMC31XX_CTRL_SET;
  392. if (mmc31xx_i2c_tx_data(data, 2) < 0) {
  393. /* assume SET always success */
  394. printk(KERN_ERR "[mmc31xx] mmc31xx set is failed\n");
  395. }
  396. /* wait external capacitor charging done for next SET/RESET */
  397. msleep(MMC31XX_DELAY_SET);
  398.  
  399. printk(KERN_ERR "[mmc31xx_probe] -\n");
  400.  
  401. return 0;
  402.  
  403. out_deregister:
  404. misc_deregister(&mmc31xx_device);
  405. out:
  406. return res;
  407. }
  408.  
  409. static int mmc31xx_remove(struct i2c_client *client)
  410. {
  411. device_remove_file(&client->dev, &dev_attr_mmc31xx);
  412. misc_deregister(&mmc31xx_device);
  413.  
  414. return 0;
  415. }
  416.  
  417. #ifdef CONFIG_PM
  418. static int mmc31xx_suspend(struct i2c_client *client, pm_message_t mesg)
  419. {
  420. struct vreg *mmc31xx_vreg = vreg_get(0, LDO_LCD);
  421. if(vreg_disable(mmc31xx_vreg))
  422. printk(KERN_ERR "vreg_disable: ldo15 vreg operation failed\n");
  423.  
  424. #if DEBUG
  425. printk(KERN_INFO "[%s]\n",__FUNCTION__);
  426. #endif
  427.  
  428. return 0;
  429. }
  430.  
  431. static int mmc31xx_resume(struct i2c_client *client)
  432. {
  433. struct vreg *mmc31xx_vreg = vreg_get(0, LDO_LCD);
  434. if(vreg_enable(mmc31xx_vreg))
  435. printk(KERN_ERR "vreg_enable: ldo15 vreg operation failed\n");
  436.  
  437. #if DEBUG
  438. printk(KERN_INFO "[%s]\n",__FUNCTION__);
  439. #endif
  440.  
  441. return 0;
  442. }
  443. #else
  444. #define mmc31xx_suspend NULL
  445. #define mmc31xx_resume NULL
  446. #endif
  447. static const struct i2c_device_id mmc31xx_id[] = {
  448. { MMC31XX_I2C_NAME, 0 },
  449. { }
  450. };
  451.  
  452. static struct i2c_driver mmc31xx_driver = {
  453. .probe = mmc31xx_probe,
  454. .remove = mmc31xx_remove,
  455. .suspend = mmc31xx_suspend,
  456. .resume = mmc31xx_resume,
  457. .id_table = mmc31xx_id,
  458. .driver = {
  459. .owner = THIS_MODULE,
  460. .name = MMC31XX_I2C_NAME,
  461. },
  462. };
  463.  
  464.  
  465. static int __init mmc31xx_init(void)
  466. {
  467. struct device *dev_t;
  468.  
  469. pr_info("mmc31xx driver: init\n");
  470. mag_class = class_create(THIS_MODULE, "magnetic");
  471.  
  472. if (IS_ERR(mag_class))
  473. return PTR_ERR( mag_class );
  474.  
  475. dev_t = device_create( mag_class, NULL, 0, "%s", "magnetic");
  476.  
  477. if (device_create_file(dev_t, &dev_attr_read_mag) < 0)
  478. printk("Failed to create device file(%s)!\n", dev_attr_read_mag.attr.name);
  479.  
  480. if (device_create_file(dev_t, &dev_attr_power_on) < 0)
  481. printk("Failed to create device file(%s)!\n", dev_attr_power_on.attr.name);
  482.  
  483. if (IS_ERR(dev_t))
  484. {
  485. return PTR_ERR(dev_t);
  486. }
  487. return i2c_add_driver(&mmc31xx_driver);
  488. }
  489.  
  490. static void __exit mmc31xx_exit(void)
  491. {
  492. pr_info("mmc31xx driver: exit\n");
  493. i2c_del_driver(&mmc31xx_driver);
  494. }
  495.  
  496. module_init(mmc31xx_init);
  497. module_exit(mmc31xx_exit);
  498.  
  499. MODULE_AUTHOR("Robbie Cao<hjcao@memsic.com>");
  500. MODULE_DESCRIPTION("MEMSIC MMC31XX Magnetic Sensor Driver");
  501. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement