ls-gl3526.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Light Sensor Driver - GL3526
  3. *
  4. * Copyright (C) 2010 Amlogic Corporation
  5. *
  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. #include <linux/platform_device.h>
  22. #include <linux/input-polldev.h>
  23. #include <linux/kernel.h>
  24. #include <linux/module.h>
  25. #include <linux/saradc.h>
  26. #define POLL_INTERVAL 2000 /* poll for input every 2s */
  27. #define LUX_LEVEL 4 /* 0~4 report 5 levels */
  28. static struct platform_device *pdev;
  29. static struct input_polled_dev *light_sensor_idev;
  30. static const int sAdcValues[LUX_LEVEL] = {
  31. 50,
  32. 100,
  33. 200,
  34. 500
  35. };
  36. struct light_sensor_info {
  37. int lux_level;
  38. int suspend;
  39. };
  40. static struct light_sensor_info ls_info;
  41. /* Sysfs Files */
  42. static ssize_t light_sensor_lux_level_show(struct device *dev,
  43. struct device_attribute *attr, char *buf)
  44. {
  45. return sprintf(buf, "(%d)\n", ls_info.lux_level);
  46. }
  47. static DEVICE_ATTR(lux_level, 0444, light_sensor_lux_level_show, NULL);
  48. static struct attribute *light_sensor_attributes[] = {
  49. &dev_attr_lux_level.attr,
  50. NULL,
  51. };
  52. static struct attribute_group light_sensor_attribute_group = {
  53. .attrs = light_sensor_attributes,
  54. };
  55. /* Device model stuff */
  56. static int light_sensor_probe(struct platform_device *dev)
  57. {
  58. printk(KERN_INFO "light_sensor: device successfully initialized.\n");
  59. return 0;
  60. }
  61. #ifdef CONFIG_PM
  62. static int light_sensor_suspend(struct platform_device *dev, pm_message_t state)
  63. {
  64. ls_info.suspend = 1;
  65. return 0;
  66. }
  67. static int light_sensor_resume(struct platform_device *dev)
  68. {
  69. ls_info.suspend = 0;
  70. return 0;
  71. }
  72. #else
  73. #define light_sensor_suspend NULL
  74. #define light_sensor_resume NULL
  75. #endif
  76. static struct platform_driver light_sensor_driver = {
  77. .probe = light_sensor_probe,
  78. .resume = light_sensor_resume,
  79. .suspend = light_sensor_suspend,
  80. .driver = {
  81. .name = "light_sensor",
  82. .owner = THIS_MODULE,
  83. },
  84. };
  85. static void light_sensor_dev_poll(struct input_polled_dev *dev)
  86. {
  87. struct input_dev *input_dev = dev->input;
  88. int adc_val, i;
  89. adc_val = get_adc_sample(6);
  90. for (i = 0; i < LUX_LEVEL; i++) {
  91. if (adc_val < sAdcValues[i])
  92. break;
  93. }
  94. if (ls_info.lux_level != i) {
  95. ls_info.lux_level = i;
  96. input_report_abs(input_dev, ABS_X, ls_info.lux_level);
  97. input_sync(input_dev);
  98. //printk(KERN_INFO "light_sensor: light_sensor_dev_poll lux_level=%d adc_val=%d\n", ls_info.lux_level, adc_val);
  99. }
  100. }
  101. /* Module stuff */
  102. static int __init light_sensor_init(void)
  103. {
  104. struct input_dev *idev;
  105. int ret;
  106. ret = platform_driver_register(&light_sensor_driver);
  107. if (ret)
  108. goto out;
  109. pdev = platform_device_register_simple("light_sensor", -1, NULL, 0);
  110. if (IS_ERR(pdev)) {
  111. ret = PTR_ERR(pdev);
  112. goto out_driver;
  113. }
  114. ret = sysfs_create_group(&pdev->dev.kobj, &light_sensor_attribute_group);
  115. if (ret)
  116. goto out_device;
  117. light_sensor_idev = input_allocate_polled_device();
  118. if (!light_sensor_idev) {
  119. ret = -ENOMEM;
  120. goto out_group;
  121. }
  122. light_sensor_idev->poll = light_sensor_dev_poll;
  123. light_sensor_idev->poll_interval = POLL_INTERVAL;
  124. /* initialize the input class */
  125. idev = light_sensor_idev->input;
  126. idev->name = "light_sensor";
  127. idev->phys = "light_sensor/input0";
  128. idev->id.bustype = BUS_ISA;
  129. idev->dev.parent = &pdev->dev;
  130. idev->evbit[0] = BIT_MASK(EV_ABS);
  131. input_set_abs_params(idev, ABS_X,
  132. 0, LUX_LEVEL, 0, 1);
  133. ret = input_register_polled_device(light_sensor_idev);
  134. if (ret)
  135. goto out_idev;
  136. printk(KERN_INFO "light_sensor: driver successfully loaded.\n");
  137. return 0;
  138. out_idev:
  139. input_free_polled_device(light_sensor_idev);
  140. out_group:
  141. sysfs_remove_group(&pdev->dev.kobj, &light_sensor_attribute_group);
  142. out_device:
  143. platform_device_unregister(pdev);
  144. out_driver:
  145. platform_driver_unregister(&light_sensor_driver);
  146. out:
  147. printk(KERN_WARNING "light_sensor: driver init failed (ret=%d)!\n", ret);
  148. return ret;
  149. }
  150. static void __exit light_sensor_exit(void)
  151. {
  152. input_unregister_polled_device(light_sensor_idev);
  153. input_free_polled_device(light_sensor_idev);
  154. sysfs_remove_group(&pdev->dev.kobj, &light_sensor_attribute_group);
  155. platform_device_unregister(pdev);
  156. platform_driver_unregister(&light_sensor_driver);
  157. printk(KERN_INFO "light_sensor: driver unloaded.\n");
  158. }
  159. module_init(light_sensor_init);
  160. module_exit(light_sensor_exit);
  161. MODULE_AUTHOR("michael.zhang@amlogic.com");
  162. MODULE_DESCRIPTION("Light Sensor Driver - GL3526");
  163. MODULE_LICENSE("GPL");