gps_power.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/platform_device.h>
  4. #include <linux/delay.h>
  5. #include <plat/gps_power.h>
  6. #include <linux/cdev.h>
  7. #include <linux/fs.h>
  8. #define GPS_POWER_MODULE_NAME "gps_power"
  9. #define GPS_POWER_DRIVER_NAME "gps_power"
  10. #define GPS_POWER_DEVICE_NAME "gps_power"
  11. #define GPS_POWER_CLASS_NAME "gps_power"
  12. static dev_t gps_power_devno;
  13. static struct cdev *gps_power_cdev = NULL;
  14. static struct device *devp=NULL;
  15. static int gps_power_probe(struct platform_device *pdev);
  16. static int gps_power_remove(struct platform_device *pdev);
  17. static ssize_t gps_power_ctrl(struct class *cla,struct class_attribute *attr,const char *buf,size_t count);
  18. static int gps_power_open(struct inode *inode,struct file *file);
  19. static int gps_power_release(struct inode *inode,struct file *file);
  20. static int gps_power_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
  21. static struct platform_driver gps_power_driver = {
  22. .probe = gps_power_probe,
  23. .remove = gps_power_remove,
  24. .driver = {
  25. .name = GPS_POWER_DRIVER_NAME,
  26. .owner = THIS_MODULE,
  27. },
  28. };
  29. static const struct file_operations gps_power_fops = {
  30. .open = gps_power_open,
  31. .release = gps_power_release,
  32. .unlocked_ioctl = gps_power_ioctl,
  33. };
  34. static struct class_attribute gps_power_class_attrs[] = {
  35. __ATTR(gps_powerctrl,S_IWUGO,NULL,gps_power_ctrl),
  36. __ATTR_NULL
  37. };
  38. static struct class gps_power_class = {
  39. .name = GPS_POWER_CLASS_NAME,
  40. .class_attrs = gps_power_class_attrs,
  41. .owner = THIS_MODULE,
  42. };
  43. static int gps_power_open(struct inode *inode,struct file *file)
  44. {
  45. int ret = 0;
  46. struct cdev * cdevp = inode->i_cdev;
  47. file->private_data = cdevp;
  48. return ret;
  49. }
  50. static int gps_power_release(struct inode *inode,struct file *file)
  51. {
  52. int ret = 0;
  53. return ret;
  54. }
  55. static int gps_power_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  56. {
  57. struct gps_power_platform_data *pdata = NULL;
  58. pdata = (struct gps_power_platform_data*)devp->platform_data;
  59. if(pdata == NULL){
  60. printk("%s platform data is required!\n",__FUNCTION__);
  61. return -1;
  62. }
  63. switch(cmd){
  64. case 0:
  65. if(pdata->power_off)
  66. pdata->power_off();
  67. break;
  68. case 1:
  69. if(pdata->power_on)
  70. pdata->power_on();
  71. break;
  72. default:
  73. break;
  74. }
  75. return 0;
  76. }
  77. static ssize_t gps_power_ctrl(struct class *cla,struct class_attribute *attr,const char *buf,size_t count)
  78. {
  79. struct gps_power_platform_data *pdata = NULL;
  80. pdata = (struct gps_power_platform_data*)devp->platform_data;
  81. if(pdata == NULL){
  82. printk("%s platform data is required!\n",__FUNCTION__);
  83. return -1;
  84. }
  85. if(!strncasecmp(buf,"on",2)){
  86. if(pdata->power_on)
  87. pdata->power_on();
  88. }
  89. else if (!strncasecmp(buf,"off",3)){
  90. if(pdata->power_off)
  91. pdata->power_off();
  92. }
  93. else{
  94. printk( KERN_ERR"%s:%s error!Not support this parameter\n",GPS_POWER_MODULE_NAME,__FUNCTION__);
  95. return -EINVAL;
  96. }
  97. return count;
  98. }
  99. static int gps_power_probe(struct platform_device *pdev)
  100. {
  101. int ret;
  102. struct gps_power_platform_data *pdata = pdev->dev.platform_data;
  103. if (!pdata) {
  104. dev_err(&pdev->dev, "platform data is required!\n");
  105. ret = -EINVAL;
  106. goto out;
  107. }
  108. ret = alloc_chrdev_region(&gps_power_devno, 0, 1, GPS_POWER_DRIVER_NAME);
  109. if (ret < 0) {
  110. printk(KERN_ERR "%s:%s failed to allocate major number\n",GPS_POWER_MODULE_NAME,__FUNCTION__);
  111. ret = -ENODEV;
  112. goto out;
  113. }
  114. ret = class_register(&gps_power_class);
  115. if (ret < 0) {
  116. printk(KERN_ERR "%s:%s failed to register class\n",GPS_POWER_MODULE_NAME,__FUNCTION__);
  117. goto error1;
  118. }
  119. gps_power_cdev = cdev_alloc();
  120. if(!gps_power_cdev){
  121. printk(KERN_ERR "%s:%s failed to allocate memory\n",GPS_POWER_MODULE_NAME,__FUNCTION__);
  122. goto error2;
  123. }
  124. cdev_init(gps_power_cdev,&gps_power_fops);
  125. gps_power_cdev->owner = THIS_MODULE;
  126. ret = cdev_add(gps_power_cdev,gps_power_devno,1);
  127. if(ret){
  128. printk(KERN_ERR "%s:%s failed to add device\n",GPS_POWER_MODULE_NAME,__FUNCTION__);
  129. goto error3;
  130. }
  131. devp = device_create(&gps_power_class,NULL,gps_power_devno,NULL,GPS_POWER_DEVICE_NAME);
  132. if(IS_ERR(devp)){
  133. printk(KERN_ERR "%s:%s failed to create device node\n",GPS_POWER_MODULE_NAME,__FUNCTION__);
  134. ret = PTR_ERR(devp);
  135. goto error3;
  136. }
  137. devp->platform_data = pdata;
  138. return 0;
  139. error3:
  140. cdev_del(gps_power_cdev);
  141. error2:
  142. class_unregister(&gps_power_class);
  143. error1:
  144. unregister_chrdev_region(gps_power_devno,1);
  145. out:
  146. return ret;
  147. }
  148. static int gps_power_remove(struct platform_device *pdev)
  149. {
  150. unregister_chrdev_region(gps_power_devno,1);
  151. class_unregister(&gps_power_class);
  152. device_destroy(NULL, gps_power_devno);
  153. cdev_del(gps_power_cdev);
  154. return 0;
  155. }
  156. static int __init init_gps(void)
  157. {
  158. int ret = -1;
  159. ret = platform_driver_register(&gps_power_driver);
  160. if (ret != 0) {
  161. printk(KERN_ERR "failed to register gps power module, error %d\n", ret);
  162. return -ENODEV;
  163. }
  164. return ret;
  165. }
  166. module_init(init_gps);
  167. static void __exit unload_gps(void)
  168. {
  169. platform_driver_unregister(&gps_power_driver);
  170. }
  171. module_exit(unload_gps);
  172. MODULE_LICENSE("GPL");
  173. MODULE_AUTHOR("AMLOGIC");
  174. MODULE_DESCRIPTION("GPS power driver");