flashlight.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Flash light char device driver.
  3. *
  4. * Author: Heming Lv <heming.lv@amlogic.com>
  5. *
  6. * Copyright (c) 2011 Amlogic Inc.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the smems of the GNU General Public License as published by
  10. * the Free Software Foundation; version 2 of the License.
  11. *
  12. */
  13. #include <linux/cdev.h>
  14. #include <linux/types.h>
  15. #include <linux/fs.h>
  16. #include <linux/device.h>
  17. #include <linux/platform_device.h>
  18. #include <media/amlogic/flashlight.h>
  19. #define FLASHLIGHT_MODULE_NAME "flashlight"
  20. #define FLASHLIGHT_DRIVER_NAME "flashlight"
  21. #define FLASHLIGHT_DEVICE_NAME "flashlight"
  22. #define FLASHLIGHT_CLASS_NAME "flashlight"
  23. static dev_t flashlight_devno;
  24. static struct cdev *flashlight_cdev=NULL;
  25. static struct device *devp=NULL;
  26. static aml_plat_flashlight_status_t flashlight_flag = FLASHLIGHT_OFF;
  27. static ssize_t flashlight_ctrl(struct class *cla, struct class_attribute *attr, const char *buf, size_t count);
  28. static ssize_t flashlight_getflag(struct class *cla, struct class_attribute *attr, char *buf);
  29. static ssize_t flashlight_setflag(struct class *cla, struct class_attribute *attr, const char *buf, size_t count);
  30. static int flashlight_open(struct inode *inode,struct file *file);
  31. static int flashlight_release(struct inode *inode,struct file *file);
  32. static int flashlight_probe(struct platform_device *pdev);
  33. static int flashlight_remove(struct platform_device *pdev);
  34. static struct platform_driver flashlight_driver = {
  35. .probe = flashlight_probe,
  36. .remove = flashlight_remove,
  37. .driver = {
  38. .name = FLASHLIGHT_DRIVER_NAME,
  39. .owner = THIS_MODULE,
  40. },
  41. };
  42. static const struct file_operations flashlight_fops = {
  43. .open = flashlight_open,
  44. .release = flashlight_release,
  45. };
  46. static struct class_attribute flashlight_class_attrs[] = {
  47. __ATTR(flashlightctrl,S_IWUGO,NULL,flashlight_ctrl),
  48. __ATTR(flashlightflag,S_IRUGO|S_IWUGO,flashlight_getflag,flashlight_setflag),
  49. __ATTR_NULL
  50. };
  51. static struct class flashlight_class = {
  52. .name = FLASHLIGHT_CLASS_NAME,
  53. .class_attrs = flashlight_class_attrs,
  54. .owner = THIS_MODULE,
  55. };
  56. static int flashlight_device_match(struct device *dev, void *data)
  57. {
  58. return (!strcmp(dev->kobj.name,(const char*)data));
  59. }
  60. struct device *flashlight_class_to_device(struct class *cla)
  61. {
  62. struct device *dev;
  63. dev = class_find_device(cla, NULL, (void*)cla->name,flashlight_device_match);
  64. if (!dev)
  65. printk("%s:%s no matched device found!\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  66. return dev;
  67. }
  68. static ssize_t flashlight_ctrl(struct class *cla, struct class_attribute *attr, const char *buf, size_t count)
  69. {
  70. aml_plat_flashlight_data_t *pdata = NULL;
  71. struct device *dev = NULL;
  72. dev = flashlight_class_to_device(cla);
  73. pdata = (aml_plat_flashlight_data_t *)dev->platform_data;
  74. if(pdata == NULL){
  75. printk("%s platform data is required!\n",__FUNCTION__);
  76. return -1;
  77. }
  78. if(!strncmp(buf,"0",1)){
  79. if(pdata->flashlight_off)
  80. pdata->flashlight_off();
  81. }
  82. else if (!strncmp(buf,"1",1)){
  83. if(pdata->flashlight_on)
  84. pdata->flashlight_on();
  85. }
  86. else{
  87. printk( KERN_ERR"%s:%s error!Not support this parameter\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  88. return -EINVAL;
  89. }
  90. return count;
  91. }
  92. static ssize_t flashlight_getflag(struct class *cla, struct class_attribute *attr, char *buf)
  93. {
  94. sprintf(buf,"%d",(int)flashlight_flag);
  95. return strlen(buf);
  96. }
  97. static ssize_t flashlight_setflag(struct class *cla, struct class_attribute *attr, const char *buf, size_t count)
  98. {
  99. if(!strlen(buf)){
  100. printk("%s parameter is required!\n",__FUNCTION__);
  101. }
  102. flashlight_flag = (aml_plat_flashlight_status_t)(buf[0]-'0');
  103. return count;
  104. }
  105. static int flashlight_open(struct inode *inode,struct file *file)
  106. {
  107. return 0;
  108. }
  109. static int flashlight_release(struct inode *inode,struct file *file)
  110. {
  111. return 0;
  112. }
  113. static int flashlight_probe(struct platform_device *pdev)
  114. {
  115. int ret;
  116. aml_plat_flashlight_data_t *pdata = NULL;
  117. ret = alloc_chrdev_region(&flashlight_devno, 0, 1, FLASHLIGHT_DRIVER_NAME);
  118. if (ret < 0) {
  119. printk(KERN_ERR "%s:%s failed to allocate major number\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  120. ret = -ENODEV;
  121. goto out;
  122. }
  123. ret = class_register(&flashlight_class);
  124. if (ret < 0) {
  125. printk(KERN_ERR "%s:%s failed to register class\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  126. goto error1;
  127. }
  128. flashlight_cdev = cdev_alloc();
  129. if ( !flashlight_cdev ) {
  130. printk(KERN_ERR "%s:%s: failed to allocate memory\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  131. ret = -ENOMEM;
  132. goto error2;
  133. }
  134. cdev_init(flashlight_cdev, &flashlight_fops);
  135. flashlight_cdev->owner = THIS_MODULE;
  136. ret = cdev_add(flashlight_cdev, flashlight_devno, 1);
  137. if (ret) {
  138. printk(KERN_ERR "%s:%s: failed to add device\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  139. goto error3;
  140. }
  141. devp = device_create(&flashlight_class, NULL, flashlight_devno, NULL, FLASHLIGHT_DEVICE_NAME);
  142. if (IS_ERR(devp)) {
  143. printk(KERN_ERR "%s:%s failed to create device node\n",FLASHLIGHT_MODULE_NAME,__FUNCTION__);
  144. ret = PTR_ERR(devp);
  145. goto error3;
  146. }
  147. printk(KERN_INFO "%s:%s device %s created\n", FLASHLIGHT_MODULE_NAME,__FUNCTION__,FLASHLIGHT_DEVICE_NAME);
  148. pdata = pdev->dev.platform_data;
  149. if (!pdata) {
  150. dev_err(&pdev->dev, "platform data is required!\n");
  151. ret = -EINVAL;
  152. goto error4;
  153. }
  154. devp->platform_data = pdata;
  155. return 0;
  156. error4:
  157. device_destroy(NULL, flashlight_devno);
  158. error3:
  159. cdev_del(flashlight_cdev);
  160. error2:
  161. class_unregister(&flashlight_class);
  162. error1:
  163. unregister_chrdev_region(flashlight_devno, 1);
  164. out:
  165. return ret;
  166. }
  167. static int flashlight_remove(struct platform_device *pdev)
  168. {
  169. unregister_chrdev_region(flashlight_devno, 1);
  170. class_unregister(&flashlight_class);
  171. device_destroy(NULL, flashlight_devno);
  172. cdev_del(flashlight_cdev);
  173. return 0;
  174. }
  175. int set_flashlight(bool mode)
  176. {
  177. aml_plat_flashlight_data_t *pdata = NULL;
  178. if(devp&&devp->platform_data){
  179. pdata = devp->platform_data;
  180. if(!mode){
  181. if(pdata->flashlight_off)
  182. pdata->flashlight_off();
  183. }
  184. else {
  185. if(pdata->flashlight_on)
  186. pdata->flashlight_on();
  187. }
  188. }
  189. }
  190. EXPORT_SYMBOL(set_flashlight);
  191. aml_plat_flashlight_status_t get_flashlightflag(void)
  192. {
  193. return flashlight_flag;
  194. }
  195. EXPORT_SYMBOL(get_flashlightflag);
  196. static int __init flashlight_init(void)
  197. {
  198. int ret = -1;
  199. ret = platform_driver_register(&flashlight_driver);
  200. if (ret != 0) {
  201. printk(KERN_ERR "failed to register flashlight driver, error %d\n", ret);
  202. return -ENODEV;
  203. }
  204. return ret;
  205. }
  206. static void __exit flashlight_exit(void)
  207. {
  208. platform_driver_unregister(&flashlight_driver);
  209. }
  210. module_init(flashlight_init);
  211. module_exit(flashlight_exit);
  212. MODULE_DESCRIPTION("AMLOGIC flashlight driver");
  213. MODULE_LICENSE("GPL");
  214. MODULE_AUTHOR("amlogic");